Merge Documents

This demo uses the DevExpress Word Processing Document API to merge multiple documents into a single file. You can merge predefined sample files or supply your own documents. To do the latter, select Upload a File in the file selection drop-down menu and upload files one at a time.

Use the Merge and Save as... dropdown button to select the output format, merge files, and download the result.

Sample document
Sample.docx
DocumentForProtection.docx



using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;

Stream MergeDocuments(List<Stream> inputStreams, DocumentFormat targetFormat, bool pdfOutput) {
    using var sourceWordProcessor = new RichEditDocumentServer();
    using var targetWordProcessor = new RichEditDocumentServer();
    var sourceDocument = sourceWordProcessor.Document;
    var targetDocument = targetWordProcessor.Document;

    for(int i = 0; i < inputStreams.Count; i++) {
        sourceWordProcessor.LoadDocument(inputStreams[i]);

        var targetSection = targetDocument.Sections[targetDocument.Sections.Count - 1];
        targetSection.UnlinkHeaderFromPrevious();
        targetSection.UnlinkFooterFromPrevious();

        targetSection.UnlinkHeaderFromPrevious(HeaderFooterType.First);
        targetSection.UnlinkFooterFromPrevious(HeaderFooterType.First);

        targetSection.UnlinkHeaderFromPrevious(HeaderFooterType.Even);
        targetSection.UnlinkFooterFromPrevious(HeaderFooterType.Even);

        AppendDocumentSection(sourceDocument, targetDocument);

        if(i < inputStreams.Count - 1) {
            targetDocument.AppendSection();
            targetDocument.Sections.Last().StartType = SectionStartType.NextPage;
        }
    }
    var outputStream = new MemoryStream();
    if(pdfOutput)
        targetWordProcessor.ExportToPdf(outputStream);
    else
        targetWordProcessor.SaveDocument(outputStream, targetFormat);

    outputStream.Position = 0;
    return outputStream;
}

void AppendDocumentSection(Document source, Document target) {
    var lastSectionIndexBeforeAppending = target.Sections.Count - 1;
    var sourceSectionCount = source.Sections.Count;

    var appendedRange = target.AppendDocumentContent(source.Range);
    target.Delete(target.Paragraphs.Get(target.CreatePosition(appendedRange.Start.ToInt() - 1)).Range);

    target.DifferentOddAndEvenPages = source.DifferentOddAndEvenPages;

    for(int i = 0; i < sourceSectionCount; i++) {
        var sourceSection = source.Sections[i];
        var targetSection = target.Sections[lastSectionIndexBeforeAppending + i];

        AppendHeader(sourceSection, targetSection, HeaderFooterType.Odd);
        AppendFooter(sourceSection, targetSection, HeaderFooterType.Odd);

        AppendHeader(sourceSection, targetSection, HeaderFooterType.Even);
        AppendFooter(sourceSection, targetSection, HeaderFooterType.Even);

        AppendHeader(sourceSection, targetSection, HeaderFooterType.First);
        AppendFooter(sourceSection, targetSection, HeaderFooterType.First);
    }
}
void AppendHeader(Section sourceSection, Section targetSection, HeaderFooterType headerFooterType) {
    if(!sourceSection.HasHeader(headerFooterType)) {
        if(targetSection.HasHeader(headerFooterType)) {
            var targetHeader = targetSection.BeginUpdateHeader(headerFooterType);
            targetHeader.Delete(targetHeader.Range);
            targetSection.EndUpdateHeader(targetHeader);
        }
        return;
    }

    var source = sourceSection.BeginUpdateHeader(headerFooterType);
    var target = targetSection.BeginUpdateHeader(headerFooterType);
    target.Delete(target.Range);
    target.InsertDocumentContent(target.Range.Start, source.Range, InsertOptions.KeepSourceFormatting);
    var emptyParagraph = target.CreateRange(target.Range.End.ToInt() - 1, 1);
    target.Delete(emptyParagraph);
    sourceSection.EndUpdateHeader(source);
    targetSection.EndUpdateHeader(target);
}
void AppendFooter(Section sourceSection, Section targetSection, HeaderFooterType headerFooterType) {
    if(!sourceSection.HasFooter(headerFooterType)) {
        if(targetSection.HasFooter(headerFooterType)) {
            var targetFooter = targetSection.BeginUpdateFooter(headerFooterType);
            targetFooter.Delete(targetFooter.Range);
            targetSection.EndUpdateFooter(targetFooter);
        }
        return;
    }

    var source = sourceSection.BeginUpdateFooter(headerFooterType);
    var target = targetSection.BeginUpdateFooter(headerFooterType);
    target.Delete(target.Range);
    target.InsertDocumentContent(target.Range.Start, source.Range, InsertOptions.KeepSourceFormatting);
    var emptyParagraph = target.CreateRange(target.Range.End.ToInt() - 1, 1);
    target.Delete(emptyParagraph);
    sourceSection.EndUpdateFooter(source);
    targetSection.EndUpdateFooter(target);
}