Aspose.Words Document Merger for .NET

The Aspose.Words Document Merger for .NET lets you programmatically join any number of Word‑compatible documents into a single output while preserving formatting, styles, page layout, headers/footers, and fields. Typical uses include assembling reports, bundling contract exhibits, or aggregating generated content for archiving.

Works headlessly on Windows, Linux, and macOS. No Microsoft Office required.

Installation and Setup

  1. Install the NuGet package Aspose.Words.
  2. Apply metered licensing at app startup to avoid evaluation watermarks. See Metered Licensing .
  3. Verify framework requirements in the Installation Guide .

Supported Inputs (selected): DOC, DOCX, DOTX/DOTM, RTF, ODT, HTML/MHTML, PDF, TXT, WordML. Supported Outputs: DOCX, DOC, PDF, HTML (fixed/flow), MHTML, ODT, RTF, images, EPUB, XPS, and more.


Quick Start: Append Multiple Documents

using Aspose.Words;

// Destination (master) document
var master = new Document();
var builder = new DocumentBuilder(master);

// Start on a clean page
builder.InsertBreak(BreakType.SectionBreakNewPage);

// Append each source with chosen import mode
ImportFormatMode mode = ImportFormatMode.KeepSourceFormatting; // or UseDestinationStyles

foreach (string path in new [] { "intro.docx", "spec.docx", "annex.rtf" })
{
    var src = new Document(path);
    master.AppendDocument(src, mode);
    // Optional: force each source to start on a new page
    builder.MoveToDocumentEnd();
    builder.InsertBreak(BreakType.SectionBreakNewPage);
}

// Refresh fields (page numbers, TOC, cross‑refs)
master.UpdateFields();
master.Save("MergedOutput.pdf");

Import Format Modes

  • KeepSourceFormatting — preserves each source’s styles and direct formatting (ideal for branded inserts).
  • UseDestinationStyles — maps identical style names to the destination’s definitions for a uniform look.

Controlled Section & Page Layout

Start each document on New Page, Continuous, or Even/Odd Page:

var sect = master.LastSection;
sect.PageSetup.SectionStart = SectionStart.NewPage; // Continuous, EvenPage, OddPage

Unify margins/page size by copying PageSetup from a template section:

var template = new Document("template.docx");
var pageSetup = template.FirstSection.PageSetup;
foreach (Section s in master.Sections)
{
    s.PageSetup.Orientation = pageSetup.Orientation;
    s.PageSetup.PageWidth  = pageSetup.PageWidth;
    s.PageSetup.PageHeight = pageSetup.PageHeight;
    s.PageSetup.TopMargin  = pageSetup.TopMargin;
    s.PageSetup.BottomMargin = pageSetup.BottomMargin;
    s.PageSetup.LeftMargin = pageSetup.LeftMargin;
    s.PageSetup.RightMargin = pageSetup.RightMargin;
}

Headers, Footers, and Watermarks

Keep source headers/footers, or replace them with a master set after the merge:

// Copy headers/footers from a master template into every section
var hft = new Document("header-footer-template.docx");
foreach (Section s in master.Sections)
{
    s.HeadersFooters.Clear();
    s.HeadersFooters.AddClone(hft.FirstSection.HeadersFooters[HeaderFooterType.HeaderPrimary]);
    s.HeadersFooters.AddClone(hft.FirstSection.HeadersFooters[HeaderFooterType.FooterPrimary]);
}

// Add a simple text watermark
foreach (Section s in master.Sections)
{
    var header = s.HeadersFooters[HeaderFooterType.HeaderPrimary] ?? new HeaderFooter(master, HeaderFooterType.HeaderPrimary);
    if (header.ParentNode == null) s.HeadersFooters.Add(header);
    var shape = new Shape(master, ShapeType.TextPlainText)
    {
        RelativeHorizontalPosition = RelativeHorizontalPosition.Page,
        RelativeVerticalPosition   = RelativeVerticalPosition.Page,
        WrapType = WrapType.None,
        Rotation = -40,
        Width = 400, Height = 100, Left = 100, Top = 200,
        BehindText = true
    };
    shape.TextPath.Text = "CONFIDENTIAL";
    header.AppendChild(shape);
}

Fields, Cross‑References, and TOC

After merging, update fields so page numbers, references, and Table of Contents match the new layout:

master.UpdateFields();
master.UpdatePageLayout();        // ensures accurate page count
master.UpdateTableLayout();       // improves complex table pagination

If you maintain a single master TOC, insert it once and let it auto‑rebuild:

var b = new DocumentBuilder(master);
b.MoveToDocumentStart();
b.InsertTableOfContents("TOC \o \h \z \u");  // classic TOC switch set
master.UpdateFields();

Password‑Protected Inputs & Secure Output

using Aspose.Words.Loading;

var load = new LoadOptions { Password = "secret" };
var protectedDoc = new Document("protected.docx", load);
master.AppendDocument(protectedDoc, ImportFormatMode.KeepSourceFormatting);

// Save encrypted PDF
using Aspose.Words.Saving;
var pdf = new PdfSaveOptions
{
    EncryptionDetails = new PdfEncryptionDetails("openPwd", "ownerPwd",
        PdfEncryptionAlgorithm.RC4_128)
    { Permissions = PdfPermissions.DisallowAll }
};
master.Save("MergedEncrypted.pdf", pdf);

Stream‑First / High‑Volume Merges

using (var output = new MemoryStream())
{
    var dst = new Document();
    foreach (Stream srcStream in sourceStreams)
    {
        using var s = srcStream; // e.g., S3/Blob stream
        var src = new Document(s); // auto‑detects format
        dst.AppendDocument(src, ImportFormatMode.UseDestinationStyles);
    }
    dst.UpdateFields();
    dst.Save(output, SaveFormat.Pdf);
    output.Position = 0;
    // return/output stream
}

Performance tips

  • Batch appends in memory; call UpdateFields() once at the end.
  • Prefer UseDestinationStyles when you want consistent styling across dozens of inputs.
  • Dispose Document instances early in long pipelines to reduce peak memory.

Handling Mixed Formats (HTML, PDF, TXT)

  • HTML/MHTML: imports with styles and images (linked or embedded).
  • PDF: pages are imported as reflowed content where possible; complex layouts are preserved during output to fixed formats (e.g., PDF).
  • TXT: appended as plain paragraphs; apply a base style after import for consistency.

Best Practices

  • Pre‑validate for corruption/passwords to avoid partial merges.
  • Choose KeepSourceFormatting when brand fidelity matters; choose UseDestinationStyles for uniform look.
  • Insert a section break before each append to protect page setup.
  • Unify headers/footers after appending if you want a single corporate template.
  • Update fields & TOC as the final step.
  • For very large batches, split into groups and merge the groups to keep memory stable.

FAQ

Can I force every source to start on a new page? Yes. Insert a section or page break before each AppendDocument call or set SectionStart to NewPage.

How do I keep destination styles while importing? Use ImportFormatMode.UseDestinationStyles in AppendDocument.

Will page numbers and TOC update automatically? Call UpdateFields() (and UpdatePageLayout() for precise pagination) after all appends.

Can I merge encrypted inputs and produce encrypted output? Yes. Provide LoadOptions.Password for inputs and use PdfSaveOptions.EncryptionDetails (or OoxmlSaveOptions.Password) for output.

Is Office required? No. Aspose.Words is a standalone library.