Combina documento de Word usando Python Docx

Tengo pocos archivos de palabras que cada uno tiene contenido específico. Me gustaría un fragmento que me muestre o me ayude a descubrir cómo combinar los archivos de Word en un solo archivo, mientras uso la biblioteca docx Python.

Por ejemplo en la librería pywin32 hice lo siguiente:

 rng = self.doc.Range(0, 0) for d in data: time.sleep(0.05) docstart = d.wordDoc.Content.Start self.word.Visible = True docend = d.wordDoc.Content.End - 1 location = d.wordDoc.Range(docstart, docend).Copy() rng.Paste() rng.Collapse(0) rng.InsertBreak(win32.constants.wdPageBreak) 

Pero necesito hacerlo mientras uso la biblioteca docx Python en lugar de win32.client

Si sus necesidades son simples, algo como esto podría funcionar:

 source_document = Document('source.docx') target_document = Document() for paragraph in source_document.paragraphs: text = paragraph.text target_document.add_paragraph(text) 

Hay cosas adicionales que puedes hacer, pero eso debería ayudarte a comenzar.

Resulta que copiar contenido de un archivo de Word a otro es bastante complejo en el caso general, que involucra cosas como los estilos de conciliación presentes en el documento de origen que pueden estar en conflicto en el documento de destino, por ejemplo. Entonces, no es una característica que probablemente estemos agregando el próximo año, por ejemplo.

He ajustado el ejemplo anterior para que funcione con la última versión de python-docx (0.8.6 en el momento de escribir este documento). Tenga en cuenta que esto solo copia los elementos (fusionar estilos de elementos es más complicado de hacer):

 from docx import Document files = ['file1.docx', 'file2.docx'] def combine_word_documents(files): merged_document = Document() for index, file in enumerate(files): sub_doc = Document(file) # Don't add a page break if you've reached the last file. if index < len(files)-1: sub_doc.add_page_break() for element in sub_doc.element.body: merged_document.element.body.append(element) merged_document.save('merged.docx') combine_word_documents(files) 

Si solo necesita combinar documentos simples con texto, puede usar python-docx como se mencionó anteriormente.

Si necesita combinar documentos que contengan hipervínculos, imágenes, listas, viñetas, etc. Puede hacerlo usando lxml para combinar el cuerpo del documento y todos los archivos de referencia, como:

  • word / styles.xml
  • palabra / numeracion.xml
  • palabra / medios
  • [Content_Types] .xml

etc.

Cree un documento vacío (empty.docx) y agregue sus dos documentos a esto. En cada bucle de la iteración sobre los archivos, agregue un salto de página si es necesario.

Al finalizar, guarde el nuevo archivo que contiene sus dos archivos combinados.

 from docx import Document files = ['file1.docx', 'file2.docx'] def combine_word_documents(files): combined_document = Document('empty.docx') count, number_of_files = 0, len(files) for file in files: sub_doc = Document(file) # Don't add a page break if you've # reached the last file. if count < number_of_files - 1: sub_doc.add_page_break() for element in sub_doc._document_part.body._element: combined_document._document_part.body._element.append(element) count += 1 combined_document.save('combined_word_documents.docx') combine_word_documents(files) 

El enfoque alternativo para fusionar dos documentos, incluyendo todos los estilos, es usar la biblioteca de python docxcompose ( https://pypi.org/project/docxcompose/ ). No necesitamos definir explícitamente el estilo y no tenemos que leer el documento párrafo por párrafo y adjuntarlo al documento maestro. El uso del docxcompose de python se muestra en el siguiente código

 #Importing the required packages from docxcompose.composer import Composer from docx import Document as Document_compose #filename_master is name of the file you want to merge the docx file into master = Document_compose(filename_master) composer = Composer(master) #filename_second_docx is the name of the second docx file doc2 = Document_compose(filename_second_docx) #append the doc2 into the master using composer.append function composer.append(doc2) #Save the combined docx with a name composer.save("combined.docx") 

Si desea combinar varios documentos en un solo archivo docx, puede usar la siguiente función

 #Filename_master is the name of the file you want to merge all the document into #files_list is a list containing all the filename of the docx file to be merged def combine_all_docx(filename_master,files_list): number_of_sections=len(files_list) master = Document_compose(filename_master) composer = Composer(master) for i in range(0, number_of_sections): doc_temp = Document_compose(files_list[i]) composer.append(doc_temp) composer.save("combined_file.docx") #For Example #filename_master="file1.docx" #files_list=["file2.docx","file3.docx","file4.docx",file5.docx"] #Calling the function #combine_all_docx(filename_master,files_list) #This function will combine all the document in the array files_list into the file1.docx and save the merged document into combined_file.docx 

Todo esto es muy útil. Combiné las respuestas de Martijn Jacobs y el Sr. Kriss.

 def combine_word_documents(input_files): """ :param input_files: an iterable with full paths to docs :return: a Document object with the merged files """ for filnr, file in enumerate(input_files): # in my case the docx templates are in a FileField of Django, add the MEDIA_ROOT, discard the next 2 lines if not appropriate for you. if 'offerte_template' in file: file = os.path.join(settings.MEDIA_ROOT, file) if filnr == 0: merged_document = Document(file) merged_document.add_page_break() else: sub_doc = Document(file) # Don't add a page break if you've reached the last file. if filnr < len(input_files)-1: sub_doc.add_page_break() for element in sub_doc.element.body: merged_document.element.body.append(element) return merged_document