【问题标题】:Merge multiple word documents into one using OpenXML and XElement使用 OpenXML 和 XElement 将多个 word 文档合并为一个
【发布时间】:2015-01-06 01:36:42
【问题描述】:

正如标题所述,我正在尝试将多个 word(.docx) 文件合并到一个 word 文档中。这些文档中的每一个都是一页长。我在这个实现中使用了来自this post 的一些代码。我遇到的问题是只有第一个文档被正确写入,每隔一个迭代都会附加一个新文档,但文档内容与第一个相同。

这是我正在使用的代码:

//list that holds the file paths
List<String> fileNames = new List<string>();
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");

//get the first document
MemoryStream mainStream = new MemoryStream();
byte[] buffer = File.ReadAllBytes(fileNames[0]);
mainStream.Write(buffer, 0, buffer.Length);

using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
{
    //xml for the new document
    XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);
    //iterate through eacah file
    for (int i = 1; i < fileNames.Count; i++)
    {
        //read in the document
        byte[] tempBuffer = File.ReadAllBytes(fileNames[i]);
        WordprocessingDocument tempDocument = WordprocessingDocument.Open(new MemoryStream(tempBuffer), true);
        //new documents XML
        XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);
        //add the new xml
        newBody.Add(tempBody);
        string str = newBody.ToString();
        //write to the main document and save
        mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
        mainDocument.MainDocumentPart.Document.Save();
        mainDocument.Package.Flush();
        tempBuffer = null;
    }
    //write entire stream to new file
    FileStream fileStream = new FileStream("xmltest.docx", FileMode.Create);
    mainStream.WriteTo(fileStream);
    //ret = mainStream.ToArray();
    mainStream.Close();
    mainStream.Dispose();
}

同样的问题是正在创建的每个新文档都与第一个文档具有相同的内容。所以当我运行它时,输出将是一个包含五个相同页面的文档。我尝试在列表中切换文档顺序并获得相同的结果,因此它不是特定于一个文档的。 谁能建议我在这里做错了什么?我正在查看它,但我无法解释我所看到的行为。任何建议,将不胜感激。非常感谢!

编辑:我认为这可能与我尝试合并的文档是使用自定义 XML 部件生成的事实有关。我认为文档中的 Xpath 以某种方式指向相同的内容。问题是我可以打开这些文档中的每一个并查看正确的内容,只是当我合并它们时我才看到问题。

【问题讨论】:

  • document.xml 是什么样的?另一种可能性是匹配 id。
  • document.xml 确认每个页面的 xpath 都绑定到相同的东西。例如 w:xpath="/project[1]/ProjectDescription[1] 。虽然这对于每个文档在合并时都可以正常工作,但它们都使用相同的源。我不确定我的选择是什么在这一点上。我需要一种方法来让每个文档在合并之前填充它们的内容。
  • linq 标签在这里不合适。
  • XElement 是 System.Xml.Linq 命名空间的一部分,所以我选择包含它。
  • 作为另一种选择,我们的 MergeDocx 产品可以合并包含自定义 xml 数据绑定的文档。

标签: c# xml linq ms-word openxml


【解决方案1】:

此解决方案使用 DocumentFormat.OpenXml

public static void Join(params string[] filepaths)
    {

     //filepaths = new[] { "D:\\one.docx", "D:\\two.docx", "D:\\three.docx", "D:\\four.docx", "D:\\five.docx" };
        if (filepaths != null && filepaths.Length > 1)

            using (WordprocessingDocument myDoc = WordprocessingDocument.Open(@filepaths[0], true))
            {
                MainDocumentPart mainPart = myDoc.MainDocumentPart;

                for (int i = 1; i < filepaths.Length; i++)
                {
                    string altChunkId = "AltChunkId" + i;
                    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
                        AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                    using (FileStream fileStream = File.Open(@filepaths[i], FileMode.Open))
                    {
                        chunk.FeedData(fileStream);
                    }
                    DocumentFormat.OpenXml.Wordprocessing.AltChunk altChunk = new DocumentFormat.OpenXml.Wordprocessing.AltChunk();
                    altChunk.Id = altChunkId;
                    //new page, if you like it...
                        mainPart.Document.Body.AppendChild(new Paragraph(new Run(new Break() { Type = BreakValues.Page })));
                    //next document
                    mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
                }
                mainPart.Document.Save();
                myDoc.Close();
            }
    }

【讨论】:

    【解决方案2】:

    您似乎合并的方式有时可能无法正常工作。您可以尝试其中一种方法

    1. http://blogs.msdn.com/b/ericwhite/archive/2008/10/27/how-to-use-altchunk-for-document-assembly.aspx 中使用 AltChunk

    2. 使用http://powertools.codeplex.com/DocumentBuilder.BuildDocument 方法

      如果您仍然遇到类似的问题,您可以在 Merge and 从 CustomXml 部分将数据分配给这些控件。您可以在 OpenXmlHelper 类的方法 AssignContentFromCustomXmlPartForDataboundControl 中找到这种方法。代码可从http://worddocgenerator.codeplex.com/下载

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多