Append DOCX files into one document.
dotnet add package RecursiveAI.OneDocument.DocumentsRequires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneDocument.Documents; using var dest = Document.Open("first.docx"); using var source = Document.Open("second.docx"); dest.Append(source); dest.SaveAs("merged.docx");
Writes merged.docx; the snippet prints nothing.
Unzip the example, then dotnet run.
Full program
The example includes first.docx with “Project summary” in a black Body style and second.docx with “Budget approved.” in a blue Body style. This deliberately creates a style conflict.
using RecursiveAI.OneDocument.Documents; using var dest = Document.Open("first.docx"); using var source = Document.Open("second.docx"); var report = dest.Append(source); dest.SaveAs("merged.docx"); Console.WriteLine($"Appended blocks: {report.CountOf("blocks")}"); foreach (var item in report.Resolutions) Console.WriteLine($"{item.Code}: {item.Resolution}"); foreach (var item in report.Loss.Items) Console.WriteLine($"{item.Code}: {item.Message}"); foreach (var item in report.Problems) Console.WriteLine($"{item.Code}: {item.Message}"); Console.WriteLine(dest.ExtractText().Trim());
dotnet run prints:
Appended blocks: 1 merge.style-conflict: kept destination Project summary Budget approved.
Combining Strict and Transitional documents (the two OOXML conformance variants) throws OfficeUnsupportedException; inspect Resolutions, Loss.Items and Problems for conflicts and content the merge did not carry over.
Variations
Keep both styles and the source section
This writes keep-both.docx, retaining the conflicting source style under a new name. KeepSource also keeps the source’s final section settings when the copied range reaches its end.
using RecursiveAI.OneDocument.Documents; using var dest = Document.Open("first.docx"); using var source = Document.Open("second.docx"); var report = dest.Append(source, new MergeOptions { Styles = StyleConflict.KeepBoth, Sections = SectionHandling.KeepSource }); dest.SaveAs("keep-both.docx"); foreach (var item in report.Resolutions) Console.WriteLine($"{item.Code}: {item.Resolution}");
Output:
merge.style-conflict: kept bothRelated recipes
The short answer
Open the first Word document as the destination, open the next as the source, call dest.Append(source), then save the destination to a new DOCX. OneDocument edits the destination in memory; the source is only read. Appending combines document bodies rather than extracting plain text, so the operation can copy tables, pictures, styles, notes and their relationships.
For production files, keep the returned MergeReport. A saved DOCX does not mean every source setting won. The full program prints resolved conflicts, losses and problems so you can decide whether its result is suitable for your documents.
Can I merge multiple Word documents into one?
Yes. Use the first document as the base and append the remaining documents in the order you want them to appear. Save once after the last append. Choose the order explicitly rather than treating a folder’s enumeration order as the document order. The first document supplies the destination’s theme, font table and document defaults.
An append copies body blocks. A block is a direct child of the document body, such as a paragraph, table or content control, excluding the final section-properties element. MergeOptions.SourceStart and SourceCount can select a range instead of the whole body. To insert at a particular block rather than at the end, use Document.Insert(index, source, options).
The merge documentation describes how relationships and identifiers are rewritten. Related parts are copied with their relationship graphs, and identical pictures with the same content type can be stored once. Bookmark names that already exist are renamed, with references in the copied content updated. Those rules are why appending document markup is different from concatenating the text of each file.
How do I merge a bunch of documents into one?
using RecursiveAI.OneDocument.Documents; string[] files = ["first.docx", "second.docx"]; using var dest = Document.Open(files[0]); foreach (string path in files.Skip(1)) { using var source = Document.Open(path); dest.Append(source); } dest.SaveAs("combined.docx"); Console.WriteLine(dest.ExtractText().Trim());
Output:
Project summary Budget approved.
The list uses the two included inputs; add filenames in the order they should appear. This writes combined.docx.
First choose a formatting policy. The default is StyleConflict.KeepDestination: styles with the same name and type are compared, and a different source definition loses to the destination’s definition. In this example, the blue source Body style becomes the black destination Body style. The report names that decision as merge.style-conflict with resolution kept destination.
Use KeepBoth, as in the variation, when copied text should use a separate source style. OneDocument adds the source definition with a name such as “Body (2)”. Use UseSource only when replacing the destination definition is intentional: existing destination text that uses it can change appearance too. Equal definitions are reused without a conflict report.
Next choose list and section behavior. Lists continue by default when their definitions and level overrides match; NumberingContinuation.Restart makes a new list instance. The default section policy uses the destination’s governing section for appended content, while section boundaries inside the copied range keep their own page setup.
For source headers and footers at the end of an appended document, use SectionHandling.KeepSource and copy through the source’s end. Headers and footers are copied when a copied section references them. This still is not a promise of identical page layout: destination fonts, theme and defaults win, data bindings can be dropped, and comment replies and resolved state are not carried. Review Loss.Items alongside Resolutions and Problems, then inspect the saved document’s appearance before distributing it.