使用 OpenXML 在内存中流式传输合并 Word 文档时“损坏”文档

“corrupt” document when Streaming In Memory Merge Word Document using OpenXML

我正在尝试在 ASP.NET MVC 5 上使用 OpenXML 合并多个 Word 文档。但是我不断收到来自 Microsoft Word 的消息,指出文档已损坏。

private Stream GenerateDocument(DocumentType documentType)
{
    using (var templateStream = File.OpenRead(GetTemplatePath(documentType)))
    {
        //some code
        var result = documentGenerator.Generate();
        return result;
    }
}

private Stream MergeDocuments(DocumentLibraryModel documentLibrary)
{
    var documentTypes = documentLibrary.DocumentTypes.GetEnumerator();
    var mainStream = GenerateDocument(documentTypes.Current);

    using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
    {

        XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);
        documentTypes.MoveNext();
        while (documentTypes.MoveNext())
        {
            WordprocessingDocument tempDocument = WordprocessingDocument.Open(GenerateDocument(documentTypes.Current), true);
            XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);

            newBody.Add(tempBody);
            mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
            mainDocument.MainDocumentPart.Document.Save();
            mainDocument.Package.Flush();
        }

    }

    return mainStream;
}

但是文档打开时显示已损坏。

有什么想法吗?

问题出在这里:

XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);    
newBody.Add(tempBody);

您将正文添加到生成无效 Word 文档的正文中。 Word文档一次只能包含一个Body。

我建议克隆元素而不是解析 XML。 你可以这样做:

using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
{
    mainDocument.MainDocumentPart.Document.Body = new Body();

    documentTypes.MoveNext();
    while (documentTypes.MoveNext())
    {
        using (WordprocessingDocument tempDocument = WordprocessingDocument.Open(GenerateDocument(documentTypes.Current)))
        {
            foreach (var element in tempDocument.MainDocumentPart.Document.Body.Elements)
            {
                mainDocument.MainDocumentPart.Document.Body.AppendChild(element.CloneNode(true));
            }
        }
    }

    mainDocument.MainDocumentPart.Document.Save();
}