2016-07-01 2 views
1

Я пытаюсь объединить несколько документов Word с помощью OpenXML на ASP.NET MVC 5. Но я постоянно получаю сообщение от Microsoft Word о том, что документ поврежден.«Коррумпированный» документ при потоковой передаче в памяти Слияние Word-документа с использованием OpenXML

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; 
} 

Однако документ открывается как поврежденный.

Любые идеи?

ответ

1

Проблема заключается в следующем:

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

Вы добавляете тело к телу, которое генерирует недействительный документ Word. Документ Word может содержать только одно тело в то время.

Я бы рекомендовал клонирование элементов вместо синтаксического разбора 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(); 
}