2011-12-23 12 views
5

Estoy tratando de crear un AddAlternativeFormatImportPart en un archivo .docx para hacer referencia a él en el documento a través de un AltChunk. el problema es que el código siguiente hace que Word lea el archivo docx y no se puede abrir.Documento dañado después de llamar AddAlternativeFormatImportPart utilizando 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(); 

Respuesta

7

Creo que podría ser la forma en que están manejando la corriente de la AlternativeFormatImportPart. Intente usar FeedData en su lugar, como en mi ejemplo a continuación.

 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

: Su respuesta es muy útil. ¿Podría darme un consejo para mi problema ... en lugar de introducir datos html en el documento de Word, quiero obtener la cadena con formato OOXML para los datos html correspondientes. No es necesario actualizar la palabra document.i quiere solo la cadena con formato ooxml ... – Saravanan

3

creo que es porque no se puede importar un AltChunk en un documento que se abre a partir de una secuencia de memoria. Tuve el mismo problema. Estaba abriendo la plantilla a partir de una secuencia de memoria, así:

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 

Esto funciona para actualizaciones normales de los controles de contenido, etc., y el documento está bien cuando se transmiten de nuevo a cliente o guardar como docx. Pero corrompe el documento al insertar un AltChunk.

La apertura de un documento desde una ruta de archivo físico funciona al insertar AltChunk así:

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 

Parece que no se puede importar un AltChunk en una secuencia de memoria, sólo puede hacerlo cuando se abre el archivo físico de escritura. ¿Alguien puede arrojar algo de luz sobre este asunto?

Cuestiones relacionadas