Поврежденный документ после вызова AddAlternativeFormatImportPart с использованием OpenXml - PullRequest
5 голосов
/ 23 декабря 2011

Я пытаюсь создать AddAlternativeFormatImportPart в файле .docx, чтобы ссылаться на него в документе через AltChunk. проблема в том, что приведенный ниже код приводит к тому, что файл docx считывается поврежденным Word и не может быть открыт.

        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();

Ответы [ 3 ]

7 голосов
/ 06 января 2012

Я думаю, что это может быть то, как вы управляете потоком из AlternativeFormatImportPart.Вместо этого попробуйте использовать FeedData, как в моем примере ниже.

        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();

        }
3 голосов
/ 06 сентября 2012

Я думаю, это потому, что вы не можете импортировать AltChunk в документ, открытый из потока памяти.Я была такая же проблема.Я открывал шаблон из потока памяти примерно так:

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

Это работает для обычных обновлений элементов управления контентом и т. Д., И документ в порядке, когда он возвращается обратно на клиент или сохраняется как docx.Но он повреждает документ при вставке AltChunk.

. Открытие документа по физическому пути к файлу работает при вставке AltChunk следующим образом:

    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

Кажется, вы не можете импортировать1012 * в поток памяти, вы можете сделать это только при открытии физического файла для записи.Кто-нибудь может пролить свет на этот вопрос?

0 голосов
/ 19 апреля 2018

Я знаю, что это старый пост, но у меня та же проблема. При использовании AltChunk в файле он работает, но не в MemoryStream. Было бы здорово, если бы кто-нибудь что-нибудь знал об этом. Вот как я запускаю WordprocessingDocument

var byteArrayWithFileFrom360 = ProcessFileHandler.GetFileContent(204735);

var wordDocMemoryStream = new MemoryStream();
wordDocMemoryStream.Write(byteArrayWithFileFrom360, 0, byteArrayWithFileFrom360.Length);

var myDoc = WordprocessingDocument.Open(wordDocMemoryStream, true);
...