pythonpython-docx

How can I use styles from an existing docx file in my new document?


I have a beautiful .docx file generated by a teammate and I would like to use the styles in it as defaults for the new documents I am generating programmatically via python-docx.

I am able to load the existing docx file but it isn't clear how to use the styles from the document in my newly created documents.

Would I need to perform the following pseudo code for each style I use from the existing file?

# Read in our template file to enable style reuse
template = Document("MyTemplate.docx")

# Create our new, empty document
doc = Document()
set_style(doc.styles['Heading 1'] = template.styles['Heading 1']
set_style(doc.styles['Title'] = template.styles['Title']
# etc

Solution

  • Copying styles is not directly supported by python.docx. But of course one can copy the XML of a style from one document to styles XML of another document. That would look like so:

    from docx import Document
    from copy import copy
    
    def copy_style(source_document: Document, target_document: Document, style_name: str):
        source_style_names = [style.name for style in source_document.styles]
        target_style_names = [style.name for style in target_document.styles]
        if style_name in source_style_names:
            source_style = source_document.styles[style_name]
            if style_name in target_style_names:
                target_document.styles[style_name].delete()
            target_document.styles.element.append(copy(source_style.element))
    
    template = Document('MyTemplate.docx')
    
    document = Document()
    
    style_name = 'Heading 1'
    copy_style(template, document, style_name)
    style_name = 'Title'
    copy_style(template, document, style_name)
        
    document.add_paragraph('Title Text', style='Title')
    document.add_paragraph('Heading 1', style='Heading 1')
    
    document.save('output.docx')
    

    But it is not really reliable as styles in source document may refer to other styles in source document having names which then are not defined in target document.

    Thus better approach is to have the MyTemplate.docx empty and only providing the styles. Then one can put the content in the document created from MyTemplate.docx by simply using the styles. Then save the result using a different name so MyTemplate.docx stays empty as template.