Passa al contenuto principale

Word agent

La classe WordAgent è un layer di manipolazione dei file .docx. Consente di leggere, modificare e creare documenti Word preservandone la struttura e la formattazione, operando tramite un formato strutturato condiviso (dizionari Python) per tutte le operazioni di lettura e scrittura.

Costruttore

WordAgent(file_bytes: bytes | None = None)
  • file_bytes (bytes | None): il contenuto binario del file .docx. Se None, viene creato un documento vuoto.

Metodi

save

Restituisce il documento corrente come sequenza di bytes.

save() -> bytes
suggerimento

I bytes restituiti possono essere scritti direttamente su file o inviati all'utente come allegato.


get_structure

Restituisce una mappa testuale leggera dell'intero documento, preservando l'ordine reale di paragrafi, tabelle e immagini.

get_structure(preview_len: int = 40) -> str
  • preview_len (int): numero massimo di caratteri per le anteprime testuali.

L'output è una stringa con un formato simile a:

DOC STRUCTURE (12 elements)
────────────────────────────────────────────────────────────
[0 ] P Heading1: "Contratto di Fornitura" (22 chars)
[1 ] P Normal: (empty text, has embedded content)
└─ IMG inline | name="logo.png" | alt="Logo aziendale" | 5.2×2.1 cm | [rId7]
[2 ] P Heading2: "1. Premesse" (11 chars)
[3 ] P Normal: "La società Alfa S.r.l. con sede in via…" (142 chars)
[4 ] T Table 3×5
│ R0: Parentela | Codice Fiscale | Cognome e nome | Luogo nascita | Data nascita
│ R1: Moglie | RSSLRA75… | Rossi Laura | Ancona | 15/03/1975
│ R2: Figlio | RSSMRC05… | Rossi Marco | Ancona | 22/11/2005
[5 ] P Normal: "I prezzi si intendono IVA esclusa…" (87 chars)
[6…8 ] P (empty ×3)
[9 ] P Normal: "Firma _______________" (21 chars)

Le tabelle mostrano il contenuto di tutte le righe. I paragrafi vuoti consecutivi vengono collassati. Le immagini e le text box sono riportate come sotto-elementi del paragrafo che le contiene.


get

Restituisce la rappresentazione strutturata completa di un elemento per indice.

get(idx: int) -> dict
  • idx (int): indice dell'elemento nella mappa del documento.

Per i paragrafi il risultato ha questa forma:

{
"type": "paragraph",
"style": "Normal",
"alignment": "center", # opzionale
"runs": [
{"text": "Testo in grassetto ", "bold": True, "size_pt": 12.0, "font": "Calibri"},
{"text": "e testo normale"}
],
"images": [...], # opzionale, se presenti immagini ancorate
"textboxes": [...] # opzionale, se presenti text box
}

Per le tabelle il risultato ha questa forma:

{
"type": "table",
"rows": [
[
{"paragraphs": [{"type": "paragraph", "style": "Normal", "runs": [{"text": "Cella A1"}]}]},
{"paragraphs": [{"type": "paragraph", "style": "Normal", "runs": [{"text": "Cella B1"}]}]}
]
]
}

Le proprietà supportate nei run sono: text, bold, italic, underline, highlight, size_pt, font, color.

informazioni

I run consecutivi con proprietà identiche vengono automaticamente compattati in un unico run per ridurre la dimensione dell'output.


get_table

Restituisce la rappresentazione strutturata di una tabella con metadati aggiuntivi.

get_table(idx: int) -> dict
  • idx (int): indice dell'elemento (deve essere una tabella).

Il risultato è identico a quello di get per le tabelle, con l'aggiunta di row_count e col_count.

warning

Solleva TypeError se l'elemento indicato non è una tabella.


edit

Sovrascrive il contenuto di un elemento utilizzando un dizionario strutturato nello stesso formato restituito da get.

edit(idx: int, content: dict) -> None
  • idx (int): indice dell'elemento da modificare.
  • content (dict): contenuto strutturato. Il campo type deve corrispondere al tipo dell'elemento ("paragraph" o "table").
suggerimento

Il flusso tipico è: leggere con get, modificare il dizionario, riscrivere con edit.

warning

Per le tabelle, se il dizionario contiene più righe di quelle esistenti, le righe aggiuntive vengono create automaticamente clonando la formattazione dall'ultima riga esistente.


edit_table_cell

Modifica il contenuto di una singola cella di una tabella.

edit_table_cell(idx: int, row: int, col: int, content: dict) -> None
  • idx (int): indice della tabella.
  • row (int): indice di riga (0-based).
  • col (int): indice di colonna (0-based).
  • content (dict): contenuto della cella. Supporta due formati:
    • Shorthand: {"text": "valore"} — modifica solo il testo preservando la formattazione esistente.
    • Completo: {"paragraphs": [{"type": "paragraph", "style": "Normal", "runs": [...]}]}

edit_table_cells

Modifica più celle di una tabella in una singola chiamata.

edit_table_cells(idx: int, edits: list[dict]) -> None
  • idx (int): indice della tabella.
  • edits (list): lista di dizionari, ciascuno con row, col e content (stesso formato di edit_table_cell).

add

Inserisce un nuovo elemento nel documento.

add(idx: int | None, content: dict) -> int
  • idx (int | None): posizione di inserimento. L'elemento viene inserito prima dell'indice specificato. Se None, viene aggiunto in coda al documento.
  • content (dict): contenuto strutturato (stesso formato di edit).

Restituisce l'indice dell'elemento appena inserito.

warning

Dopo un add o un remove, gli indici degli elementi successivi cambiano. È necessario richiamare get_structure per ottenere gli indici aggiornati.


remove

Rimuove uno o più elementi dal documento per indice.

remove(ids: list[int]) -> None
  • ids (list[int]): lista degli indici da rimuovere.
informazioni

Gli indici vengono processati in ordine decrescente internamente, quindi non è necessario preoccuparsi dello shift degli indici all'interno della stessa chiamata.


add_table_row

Aggiunge una riga a una tabella, ereditando la formattazione (bordi, font, dimensioni) da una riga esistente.

add_table_row(idx: int, after_row: int | None = None, values: list[str] | None = None) -> int
  • idx (int): indice della tabella.
  • after_row (int | None): inserisce dopo questa riga. None aggiunge in coda.
  • values (list[str] | None): valori testuali, uno per colonna.

Restituisce l'indice della nuova riga.


remove_table_row

Rimuove una riga da una tabella.

remove_table_row(idx: int, row: int) -> None
  • idx (int): indice della tabella.
  • row (int): indice della riga da rimuovere (0-based).

add_table_col

Aggiunge una colonna a una tabella, ereditando la formattazione dalla colonna adiacente.

add_table_col(idx: int, after_col: int | None = None, header: str = "", default: str = "") -> int
  • idx (int): indice della tabella.
  • after_col (int | None): inserisce dopo questa colonna. None aggiunge in coda.
  • header (str): testo per la cella di intestazione (riga 0).
  • default (str): testo predefinito per tutte le altre righe.

Restituisce l'indice della nuova colonna.


remove_table_col

Rimuove una colonna da una tabella.

remove_table_col(idx: int, col: int) -> None
  • idx (int): indice della tabella.
  • col (int): indice della colonna da rimuovere (0-based).

Cerca un testo nell'intero documento (paragrafi e celle di tabella), con contesto circostante.

search(query: str, context_chars: int = 30) -> list[dict]
  • query (str): testo da cercare (case-insensitive).
  • context_chars (int): numero di caratteri di contesto prima e dopo il match.

Restituisce una lista di dizionari:

[
{
"idx": 4,
"location": "P", # "P" per paragrafi, "T R1C2" per celle
"snippet": "…sottoscritto/a **Rossi** Lorenzo…"
}
]
informazioni

La ricerca non richiede alcun LLM ed è eseguita direttamente sul documento.


get_image_bytes

Estrae i bytes di un'immagine dal documento tramite il suo relationship ID.

get_image_bytes(r_id: str) -> tuple[bytes, str]
  • r_id (str): il relationship ID dell'immagine (ottenibile da get_structure o da get).

Restituisce una tupla (image_bytes, format) dove format è una stringa come "png" o "jpg".

warning

Solleva KeyError se il relationship ID non viene trovato nel documento.