2011-12-23 14 views
5

Próbuję utworzyć AddAlternativeFormatImportPart w pliku .docx w celu odniesienia go w dokumencie za pośrednictwem AltChunk. Problem polega na tym, że poniższy kod powoduje, że plik docx jest odczytywany jako uszkodzony przez program Word i nie można go otworzyć.Uszkodzony dokument po wywołaniu AddAlternativeFormatImportPart przy użyciu OpenXml

 string html = "some html code." 

     string altChunkId = "html234"; 
     var document = WordprocessingDocument.Open(inMemoryPackage, true); 
     var mainPart = document.MainDocumentPart.Document; 
     var mainDocumentPart = document.MainDocumentPart; 

     AlternativeFormatImportPart chunk = mainDocumentPart.AddAlternativeFormatImportPart 
      (AlternativeFormatImportPartType.Xhtml, altChunkId); 

     Stream contentStream = chunk.GetStream(FileMode.Open,FileAccess.ReadWrite); 
     StreamWriter contentWriter = new StreamWriter(contentStream); 
     contentWriter.Write(html); 
     contentWriter.Flush(); 

     { 
      ... 
     } 

     mainPart.Save(); 

Odpowiedz

7

Myślę, że może to być sposób, w jaki przekazujesz strumień z AlternativeFormatImportPart. Spróbuj użyć FeedData zamiast, jak w moim przykładzie poniżej.

 StringBuilder xhtmlBuilder = new StringBuilder(); 
     xhtmlBuilder.Append("<html>"); 
     xhtmlBuilder.Append("<body>"); 
     xhtmlBuilder.Append("<b>Hello world!</b>"); 
     xhtmlBuilder.Append("</body>"); 
     xhtmlBuilder.Append("</html>"); 

     using (WordprocessingDocument doc = WordprocessingDocument.Open(inputFilePath, true)) 
     { 
      string altChunkId = "chunk1"; 
      AlternativeFormatImportPart chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart 
       (AlternativeFormatImportPartType.Xhtml, altChunkId); 

      using (MemoryStream xhtmlStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(xhtmlBuilder.ToString()))) 
      { 
       chunk.FeedData(xhtmlStream); 

       AltChunk altChunk = new AltChunk(); 
       altChunk.Id = altChunkId; 
       doc.MainDocumentPart.Document.Body.Append(altChunk); 
      } 

      doc.MainDocumentPart.Document.Save(); 

     } 
+0

: Twoja odpowiedź jest bardzo przydatna. Czy możesz podać mi wskazówkę dotyczącą mojego problemu ... zamiast podawania danych html do dokumentu programu Word, chcę uzyskać sformatowany ciąg OOXML dla odpowiednich danych html. Nie trzeba aktualizować słowo document.i chce tylko sformatowanego łańcucha ooxml ... – Saravanan

3

Myślę, że to dlatego, że nie można importować AltChunk do dokumentu, który jest otwarty od strumienia pamięci. Miałem ten sam problem. I było otwarcie szablonu ze strumienia pamięci tak:

Private Sub UpdateDoc(templatePath As String) 
    Using fs As FileStream = File.OpenRead(templatePath) 
     Using ms As New MemoryStream 
      CopyStream(fs, ms) 
      Using doc As WordprocessingDocument = WordprocessingDocument.Open(ms, True) 
       'update the document 
       doc.MainDocumentPart.Document.Save() 
      End Using 
     End Using 
    End Using 
End Sub 

Private Sub CopyStream(source As Stream, target As Stream) 
    Dim buffer() As Byte 
    Dim bytesRead As Integer = 1 

    ReDim buffer(32768) 

    While bytesRead > 0 
     bytesRead = 0 
     bytesRead = source.Read(buffer, 0, buffer.Length) 
     target.Write(buffer, 0, bytesRead) 
    End While 
End Sub 

Działa to dla normalnych aktualizacjach kontroli treści itp a dokument jest w porządku, gdy przesyłane z powrotem do klienta lub zapisane jako docx. Ale to psuje dokument podczas wstawiania AltChunk.

Otwieranie dokumentu z fizycznej ścieżki pliku działa po włożeniu AltChunk tak:

Using doc As WordprocessingDocument = WordprocessingDocument.Open(strTempFile, True) 
     Dim altChunkId As String = "AltChunkId1" 
     Dim mainDocPart As MainDocumentPart = doc.MainDocumentPart 

     Dim chunk As AlternativeFormatImportPart = mainDocPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Xhtml, 
                   altChunkId) 
     Dim strHTML As String = "<html><head/><body><h1>Html Heading</h1><p>This is an html document in a string literal.</p></body></html>" 
     Using chunkStream As Stream = chunk.GetStream(FileMode.Create, FileAccess.Write) 
      Using sr As StreamWriter = New StreamWriter(chunkStream) 
       sr.Write(strHTML) 
      End Using 
     End Using 

     Dim altChunk As New AltChunk 
     altChunk.Id = altChunkId 

     mainDocPart.Document.Body.InsertAfter(altChunk, mainDocPart.Document.Body.Elements(Of Paragraph)().Last()) 
     mainDocPart.Document.Save() 
    End Using 

Wydaje się, że nie można importować AltChunk do strumienia pamięci, można tylko zrobić to po otwarciu pliku fizycznego dla pisanie. Czy ktoś może rzucić trochę światła na tę sprawę?