Buscar y reemplazar texto en un archivo .docx – Python

He estado buscando mucho un método para encontrar y reemplazar texto en un archivo docx con poca suerte. He probado el módulo docx y no pude hacer que funcionara. Finalmente, resolví el método descrito a continuación utilizando el módulo zipfile y reemplazando el archivo document.xml en el archivo docx. Para que esto funcione, necesita una plantilla de documento (docx) con el texto que desea reemplazar como cadenas únicas que no podrían coincidir con ningún otro texto existente o futuro en el documento (por ejemplo, “La reunión con XXXCLIENTNAMEXXX en XXXMEETDATEXXX fue muy bien”. “).

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() 

Mi pregunta es ¿qué hay de malo con este método? Soy bastante nuevo en esto, así que siento que alguien más debería haberlo resuelto ya. Lo que me lleva a creer que hay algo muy malo en este enfoque. ¡Pero funciona! ¿Que me estoy perdiendo aqui?

.

Aquí hay un tutorial de mi proceso de pensamiento para todos los demás que intentan aprender esto:

Paso 1) Prepare un diccionario de Python de las cadenas de texto que desea reemplazar como claves y el nuevo texto como elementos (por ejemplo, {“XXXCLIENTNAMEXXX”: “Joe Bob”, “XXXMEETDATEXXX”: “31 de mayo de 2013”}).

Paso 2) Abra el archivo docx de la plantilla usando el módulo zipfile.

Paso 3) Abra un nuevo archivo docx con el modo de acceso adjunto.

Paso 4) Extraiga el document.xml (donde vive todo el texto) del archivo docx de la plantilla y lea el xml con una variable de cadena de texto.

Paso 5) Use un bucle for para reemplazar todo el texto definido en su diccionario en la cadena de texto xml con su nuevo texto.

Paso 6) Escribe la cadena de texto xml en un nuevo archivo xml temporal.

Paso 7) Use un bucle for y el módulo zipfile para copiar todos los archivos en el archivo docx de la plantilla a un nuevo archivo docx EXCEPTO el archivo word / document.xml.

Paso 8) Escriba el archivo temporal xml con el texto reemplazado en el nuevo archivo docx como un nuevo archivo word / document.xml.

Paso 9) Cierra tu plantilla y nuevos archivos docx.

Paso 10) ¡Abre tu nuevo documento docx y disfruta del texto reemplazado!

–Editar– Falta el paréntesis de cierre ‘)’ en las líneas 7 y 11

A veces, la palabra hace cosas extrañas. Debe intentar eliminar el texto y volver a escribirlo en un solo trazo , por ejemplo, sin editar el texto en el medio

Su documento se guarda en un archivo xml (generalmente en word / document.xml para docx, después de descomprimirlo). A veces es posible que su texto no esté en un solo trazo: es posible que en algún lugar del documento, estén XXXCLIENTES y en otros lugares estén NAMEXXX.

Algo como esto:

XXXCLIENT ... NAMEXXX

Esto sucede con frecuencia debido a la compatibilidad con el idioma: la palabra divide las palabras cuando piensa que una palabra es de un idioma específico, y puede hacerlo entre palabras, que dividirá las palabras en varias tags.

El único problema con su solución es que debe escribir todo de una vez, lo que no es el más fácil de usar.

He creado una biblioteca JS que usa tags similares a bigotes: {clientName} https://github.com/edi9999/docxgenjs

Funciona globalmente de la misma manera que su algoritmo, pero no se bloqueará si el contenido no está en un solo trazo (cuando escribe {nombre de cliente} en Word, el texto generalmente se dividirá: {, nombre de cliente,} en el documento.

Puedes intentar una solución. Use la búsqueda / reemplazo de Word para obtener el texto en un solo trazo.

Por ejemplo, busque "XXXCLIENTNAMEXXX" y reemplácelo nuevamente con "XXXCLIENTNAMEXXX" .