使用WordProcessingDocument合并Word文档

时间:2016-05-30 14:37:10

标签: c# ms-word openxml

我目前正在开发一个程序,在该程序中,用户应该能够将多个Word文档合并为一个,而不会丢失任何格式,标题等。这些文件应该一个接一个地堆叠起来,不做任何改动。

这是我目前的代码:

public virtual Byte[] MergeWordFiles(IEnumerable<SendData> sourceFiles)
{
    int f = 0;
    // If only one Word document then skip merge.
    if (sourceFiles.Count() == 1)
    {
        return sourceFiles.First().File;
    }
    else
    {
        MemoryStream destinationFile = new MemoryStream();

        // Add first file
        var firstFile = sourceFiles.First().File;

        destinationFile.Write(firstFile, 0, firstFile.Length);
        destinationFile.Position = 0;

        int pointer = 1;
        byte[] ret;

        // Add the rest of the files
        try
        {
            using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(destinationFile, true))
            {
                XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);

                for (pointer = 1; pointer < sourceFiles.Count(); pointer++)
                {
                    WordprocessingDocument tempDocument = WordprocessingDocument.Open(new MemoryStream(sourceFiles.ElementAt(pointer).File), true);
                    XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);
                    newBody.Add(XElement.Parse(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new Run(new Break { Type = BreakValues.Page })).OuterXml));
                    newBody.Add(tempBody);

                    mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
                    mainDocument.MainDocumentPart.Document.Save();
                    mainDocument.Package.Flush();
                }
            }
        }
        catch (OpenXmlPackageException oxmle)
        {
            throw new Exception(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), oxmle);
        }
        catch (Exception e)
        {
            throw new Exception(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), e);
        }
        finally
        {
            ret = destinationFile.ToArray();
            destinationFile.Close();
            destinationFile.Dispose();
        }

        return ret;
    }
}

这里的问题是格式从第一个文档复制并应用到所有其余文件,这意味着例如第二个文档中的不同标题将被忽略。我该如何防止这种情况?

我一直在寻找使用SectionMarkValues.NextPage将文档分成几个部分,以及使用altChunk。

后者的问题是altChunk似乎无法将MemoryStream处理成&#34; FeedData&#34;方法

1 个答案:

答案 0 :(得分:0)

DocIO是一个.NET库,可以读取,写入,合并和呈现Word 2003/2007/2010/2013/2016文件。如果您符合条件,则可以通过community license program免费获得整套控件(商业应用程序)。社区许可是完整的产品,没有任何限制或水印。

第1步:创建控制台应用程序
第2步:添加对 Syncfusion.DocIO.Base,Syncfusion.Compression.Base Syncfusion.OfficeChart.Base 的引用;您也可以使用NuGet将这些引用添加到您的项目中 第3步:复制&amp;粘贴以下代码段。

此代码段将根据您的要求生成文档;每个输入Word文档将与其原始格式,样式和页眉/页脚合并。

using Syncfusion.DocIO.DLS;
using Syncfusion.DocIO;
using System.IO;

namespace DocIO_MergeDocument
{
class Program
{
    static void Main(string[] args)
    {
        //Boolean to indicate whether any of the input document has different odd and even headers as true
        bool isDifferentOddAndEvenPagesEnabled = false;
        // Creating a new document.
        using (WordDocument mergedDocument = new WordDocument())
        {
            //Get the files from input directory
            DirectoryInfo dirInfo = new DirectoryInfo(System.Environment.CurrentDirectory + @"\..\..\Data");
            FileInfo[] fileInfo = dirInfo.GetFiles();
            for (int i = 0; i < fileInfo.Length; i++)
            {
                if (fileInfo[i].Extension == ".doc" || fileInfo[i].Extension == ".docx")
                {
                    using (WordDocument sourceDocument = new WordDocument(fileInfo[i].FullName))
                    {
                        //Check whether the document has different odd and even header/footer
                        if (!isDifferentOddAndEvenPagesEnabled)
                        {
                            foreach (WSection section in sourceDocument.Sections)
                            {
                                isDifferentOddAndEvenPagesEnabled = section.PageSetup.DifferentOddAndEvenPages;
                                if (isDifferentOddAndEvenPagesEnabled)
                                    break;
                            }
                        }
                        //Sets the breakcode of First section of source document as NoBreak to avoid imported from a new page
                        sourceDocument.Sections[0].BreakCode = SectionBreakCode.EvenPage;
                        //Imports the contents of source document at the end of merged document
                        mergedDocument.ImportContent(sourceDocument, ImportOptions.KeepSourceFormatting);
                    }
                }
            }
            //if any of the input document has different odd and even headers as true then
            //Copy the content of the odd header/foort and add the copied content into the even header/footer
            if (isDifferentOddAndEvenPagesEnabled)
            {
                foreach (WSection section in mergedDocument.Sections)
                {
                    section.PageSetup.DifferentOddAndEvenPages = true;
                    if (section.HeadersFooters.OddHeader.Count > 0 && section.HeadersFooters.EvenHeader.Count == 0)
                    {
                        for (int i = 0; i < section.HeadersFooters.OddHeader.Count; i++)
                            section.HeadersFooters.EvenHeader.ChildEntities.Add(section.HeadersFooters.OddHeader.ChildEntities[i].Clone());
                    }
                    if (section.HeadersFooters.OddFooter.Count > 0 && section.HeadersFooters.EvenFooter.Count == 0)
                    {
                        for (int i = 0; i < section.HeadersFooters.OddFooter.Count; i++)
                            section.HeadersFooters.EvenFooter.ChildEntities.Add(section.HeadersFooters.OddFooter.ChildEntities[i].Clone());
                    }
                }
            }
            //If there is no document to merge then add empty section with empty paragraph
            if (mergedDocument.Sections.Count == 0)
                mergedDocument.EnsureMinimal();
            //Saves the document in the given name and format
            mergedDocument.Save("result.docx", FormatType.Docx);
        }
    }
}

}

Downloadable Demo

  

注意:有一个Word文档(非部分)级别设置   为奇数页和偶数页应用不同的页眉/页脚。每个输入   文档可以具有此属性的不同值。如果有的话   输入文件有不同的奇数和偶数页眉/页脚为真,它   会影响结果中页眉/页脚的视觉外观   文献。因此,如果任何输入文档具有不同的奇数和   甚至页眉/页脚,然后生成Word文档   替换为奇数页眉/页脚内容。

有关DocIO的更多信息,请参阅我们的help documentation

注意:我为Syncfusion工作