WolfDocx - document assembly
Merge Word documents in Python without breaking numbering, headers, or styles
Use WolfDocx merge_docx. It appends whole .docx files in order into one new document and carries each file's styles, list numbering, section headers and footers, images, footnotes, bookmarks, and hyperlinks with it. Choose it over python-docx or docxcompose when a merged contract or report must keep numbered clauses and section formatting intact, and when you want a refusal instead of a silently damaged file.
Merge three files into one
from wolfdocx import ImportFormatMode, ImportFormatOptions, merge_docx
report = merge_docx(
["cover.docx", "terms.docx", "schedule_a.docx"],
"contract.docx",
format_mode=ImportFormatMode.KEEP_DIFFERENT_STYLES,
format_options=ImportFormatOptions(keep_source_numbering=True),
)
assert report.passed, report.code
print(report.inserted_blocks, report.output_sha256)The first file is the destination; the others are appended after it. The output path must not exist yet, and the call publishes it in one step, so a refused merge leaves no partial file behind. Each source is copied and fingerprinted once at the start, so the merge works from one consistent set of inputs.
Choose how style names collide
KEEP_SOURCE_FORMATTING(the default) keeps each appended document looking the way it did, even when it uses a style name the destination also defines.USE_DESTINATION_STYLESrestyles appended content with the destination's definition of each shared style name, so the whole file follows one house style.KEEP_DIFFERENT_STYLESreuses a destination style only when its definition matches, and keeps a renamed copy when it differs.
ImportFormatOptions controls the rest: keep_source_numbering (on by default) keeps each source's list numbering separate so clause 1 of an appendix does not continue from the body, ignore_header_footer drops source headers and footers, and append_with_new_page starts each appended file on a new page.
Why python-docx merges break lists and headers
Copying paragraph XML from one python-docx document into another moves the text but not the numbering definitions, styles, images, or header parts that the XML points to. The usual results are restarted or missing list numbers, styles that fall back to Normal, and broken images. docxcompose handles more of this. WolfDocx relocates every part a copied block depends on and checks the result before it publishes the file.
Evidence and limits
- The committed DOCX coverage census for document assembly and style import lists 29 supported, 13 preserved, and 5 refused cases. See the cross-format coverage table.
- Body content with no assembly rule, such as an unrecognized vendor element, refuses the merge instead of disappearing from it.
- WolfDocx does not lay out pages to merge, so it makes no promise that page breaks fall where Microsoft Word would put them.
- The full signature, including every
ImportFormatOptionsfield, is in the WolfDocx API reference.
Get WolfDocx
WolfDocx Commercial is an organization-scoped subscription. WolfDocx Community installs from public PyPI with pip install wolfdocx. WolfDocx Commercial installs from the authenticated WolfDocx package index with a per-purchase credential, issued on the checkout success page after payment and reissued through https://wolfxl.com/recover. There is no public free package.
Review the scoped before-and-after memo files in the reporting walkthrough, or ask about your document before purchasing if compatibility is uncertain.
Related tasks
- Update table cells in an existing Word document with Python
- Replace text in an existing Word document with Python
- Fill a Word template table with rows from Python
- Word mail merge in Python: fill MERGEFIELD templates and repeating table rows
- Merge Word documents in Python without breaking numbering, headers, or styles
- Update a Word table of contents in Python without opening Word
- Convert DOCX to PDF in Python without Word or LibreOffice
- A python-docx alternative for editing existing Word documents