2013-05-31 36 views
10

Ho cercato molto per trovare e sostituire un testo in un file docx con un po 'di fortuna. Ho provato il modulo docx e non ho potuto farlo funzionare. Alla fine ho elaborato il metodo descritto di seguito utilizzando il modulo zipfile e sostituendo il file document.xml nell'archivio docx. Affinché ciò funzioni, è necessario un documento modello (docx) con il testo che si desidera sostituire come stringhe univoche che non potrebbero eventualmente corrispondere a nessun altro testo esistente o futuro nel documento (ad esempio "L'incontro con XXXCLIENTNAMEXXX su XXXMEETDATEXXX è andato molto bene. ").Trova e sostituisci testo nel file .docx - Python

import zipfile 

replaceText = {"XXXCLIENTNAMEXXX" : "Joe Bob", "XXXMEETDATEXXX" : "May 31, 2013"} 
templateDocx = zipfile.ZipFile("C:/Template.docx") 
newDocx = zipfile.ZipFile("C:/NewDocument.docx", "a") 

with open(templateDocx.extract("word/document.xml", "C:/")) as tempXmlFile: 
    tempXmlStr = tempXmlFile.read() 

for key in replaceText.keys(): 
    tempXmlStr = tempXmlStr.replace(str(key), str(replaceText.get(key))) 

with open("C:/temp.xml", "w+") as tempXmlFile: 
    tempXmlFile.write(tempXmlStr) 

for file in templateDocx.filelist: 
    if not file.filename == "word/document.xml": 
     newDocx.writestr(file.filename, templateDocx.read(file)) 

newDocx.write("C:/temp.xml", "word/document.xml") 

templateDocx.close() 
newDocx.close() 

La mia domanda è cosa c'è di sbagliato in questo metodo? Sono abbastanza nuovo a questa roba, quindi credo che qualcun altro avrebbe dovuto già capirlo. Il che mi porta a credere che ci sia qualcosa di molto sbagliato in questo approccio. Ma funziona! Cosa mi manca qui?

.

Ecco una guida del mio processo di pensiero per tutti gli altri cercando di imparare questa roba:

Fase 1) Preparare un dizionario Python delle stringhe di testo che si desidera sostituire come chiavi e il nuovo testo come elementi (ad esempio . {"XXXCLIENTNAMEXXX": "Joe Bob", "XXXMEETDATEXXX": "31 maggio 2013"}).

Passaggio 2) Aprire il file docx del modello utilizzando il modulo zipfile.

Passaggio 3) Aprire un nuovo nuovo file docx con la modalità di accesso append.

Passaggio 4) Estrarre il file document.xml (dove tutto il testo è presente) dal file docx del modello e leggere l'xml in una variabile di stringa di testo.

Passaggio 5) Utilizzare un ciclo for per sostituire tutto il testo definito nel dizionario nella stringa di testo xml con il nuovo testo.

Passaggio 6) Scrivere la stringa di testo xml in un nuovo file xml temporaneo.

Passaggio 7) Utilizzare un ciclo for e il modulo zipfile per copiare tutti i file nell'archivio del modello docx in un nuovo archivio docx TRANNE il file word/document.xml.

Passaggio 8) Scrivere il file xml temporaneo con il testo sostituito nel nuovo archivio docx come nuovo file word/document.xml.

Passaggio 9) Chiudere il modello e i nuovi archivi docx.

Passo 10) Apri il tuo nuovo documento docx e goditi il ​​testo sostituito!

--Edit-- mancante chiusura parentesi ')' sulle linee 7 e 11

+0

Intendi che il codice che hai pubblicato funziona e ti stai chiedendo, "Perché nessun altro l'ha fatto?" Forse qualcuno lo ha fatto. Perché questo sarebbe un problema? Da una rapida occhiata al tuo codice, sembra la cosa giusta da fare. –

+0

Ovviamente le persone lo hanno già fatto. Questa è un'implementazione barebone di una lettera tipo. Microsoft Word (e OpenOffice e così via) hanno una funzione "Stampa unione" che lo farà in modo nativo. –

+0

Questa domanda sembra essere off-topic perché riguarda la revisione del codice funzionante. Consiglia la migrazione a codereview.SE –

risposta

1

A volte, Word fa cose strane. Si dovrebbe cercare di rimuovere il testo e riscriverlo in un colpo, ad esempio, senza modificare il testo in mezzo

il documento viene salvato in un file XML (di solito in word/document.xml per docx, afer decompressione). A volte è possibile che il tuo testo non sia in un colpo solo: è possibile che da qualche parte nel documento, sia XXXCLIENT e da qualche altra parte sia NAMEXXX.

Qualcosa di simile a questo:

<w:t> XXXCLIENT </w:t> ... <w:t> NAMEXXX </w:t>

Questo accade molto spesso a causa del supporto per la lingua: parola divide le parole quando pensa che una parola è di un linguaggio specifico, e può farlo tra le parole, che la volontà dividere le parole in più tag.

Unico problema con la soluzione è che è necessario scrivere tutto in un colpo solo, che non è il più user-friendly.

Ho creato una libreria JS che usa i baffi come i tag: {} clientName https://github.com/edi9999/docxgenjs

Funziona a livello globale lo stesso come l'algoritmo, ma non vada in crash se il contenuto non è in un colpo (quando si scrive { clientName} in Word, il testo di solito è a spacco: {, clientName,} nel documento

-1

si può provare una soluzione di ricerca Usa Word/sostituire per ottenere il testo in un colpo

, ad esempio... cercare "XXXCLIENTNAMEXXX" e sostituirlo di nuovo con "XXXCLIENTNAMEXXX".

Problemi correlati