使用OpenXml调用AddAlternativeFormatImportPart后损坏文档
本文关键字:损坏 文档 AddAlternativeFormatImportPart OpenXml 调用 使用 | 更新日期: 2023-09-27 18:18:37
我试图在.docx文件中创建一个AddAlternativeFormatImportPart,以便通过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();
我认为这可能是你如何处理来自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();
}
我认为这是因为您无法将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
似乎您不能将AltChunk
导入内存流,您只能在打开物理文件进行写入时才能这样做。有人能解释一下这件事吗?
我知道这是一个旧的帖子,但我有同样的问题。当在文件中使用AltChunk时,它会起作用,但在MemoryStream中不起作用。如果有人知道这事就太好了。这就是我如何启动WordprocessingDocument
var byteArrayWithFileFrom360 = ProcessFileHandler.GetFileContent(204735);
var wordDocMemoryStream = new MemoryStream();
wordDocMemoryStream.Write(byteArrayWithFileFrom360, 0, byteArrayWithFileFrom360.Length);
var myDoc = WordprocessingDocument.Open(wordDocMemoryStream, true);