【问题标题】:Merging Word documents using WordProcessingDocument使用 WordProcessingDocument 合并 Word 文档
【发布时间】:2016-05-30 14:37:10
【问题描述】:

我目前正在开发一个程序,在该程序中,用户应该能够将多个 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 处理到它的“FeedData”方法中。

【问题讨论】:

  • 你的 SendData 对象是什么?
  • SendData 类型包含稍后在程序中使用的信息(例如文件是否应该保存到光盘或通过电子邮件发送)。合并只需要 File 属性,该属性包含字节数组格式的文档。

标签: c# ms-word openxml


【解决方案1】:

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

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

此代码 sn-p 将根据您的要求生成文档;每个输入的 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 工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    相关资源
    最近更新 更多