将 HTML 字符串添加到 OpenXML (*.docx) 文档中

本文关键字:docx 文档 OpenXML HTML 字符串 添加 | 更新日期: 2023-09-27 18:26:42

我正在尝试使用Microsoft的OpenXML 2.5库来创建OpenXML文档。一切都很好,直到我尝试将 HTML 字符串插入我的文档中。我已经搜索了网络,这是到目前为止我想出的(截图到我遇到问题的部分(:

Paragraph paragraph = new Paragraph();
Run run = new Run();
string altChunkId = "id1";
AlternativeFormatImportPart chunk =
       document.MainDocumentPart.AddAlternativeFormatImportPart(
           AlternativeFormatImportPartType.Html, altChunkId);
chunk.FeedData(new MemoryStream(Encoding.UTF8.GetBytes(ioi.Text)));
AltChunk altChunk = new AltChunk { Id = altChunkId };
run.AppendChild(new Break());
paragraph.AppendChild(run);
body.AppendChild(paragraph);

显然,我实际上并没有在这个例子中添加 altChunk,但我尝试在任何地方附加它 - 到运行、段落、正文等。在任何情况下,我都无法在Word 2010中打开docx文件。

这让我有点疯狂,因为它似乎应该很简单(我承认我没有完全理解 AltChunk"的东西"(。将不胜感激任何帮助。

旁注:我确实发现的一件事很有趣,我不知道这是否真的是一个问题,那就是这个响应说 AltChunk 在从 MemoryStream 工作时会损坏文件。谁能确认这是/不是真的?

将 HTML 字符串添加到 OpenXML (*.docx) 文档中

我可以重现错误"...内容有问题">通过使用不完整的 HTML 文档作为替代格式导入部分的内容。例如,如果您使用以下 HTML 代码段<h1>HELLO</h1>MS Word 无法打开文档。

下面的代码演示如何向 Word 文档添加AlternativeFormatImportPart。(我已经用MS Word 2013测试了代码(。

using (WordprocessingDocument doc = WordprocessingDocument.Open(@"test.docx", true))
{
  string altChunkId = "myId";
  MainDocumentPart mainDocPart = doc.MainDocumentPart;
  var run = new Run(new Text("test"));
  var p = new Paragraph(new ParagraphProperties(
       new Justification() { Val = JustificationValues.Center }),
                     run);
  var body = mainDocPart.Document.Body;
  body.Append(p);        
  MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body><h1>HELLO</h1></body></html>"));
  // Uncomment the following line to create an invalid word document.
  // MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<h1>HELLO</h1>"));
  // Create alternative format import part.
  AlternativeFormatImportPart formatImportPart =
     mainDocPart.AddAlternativeFormatImportPart(
        AlternativeFormatImportPartType.Html, altChunkId);
  //ms.Seek(0, SeekOrigin.Begin);
  // Feed HTML data into format import part (chunk).
  formatImportPart.FeedData(ms);
  AltChunk altChunk = new AltChunk();
  altChunk.Id = altChunkId;
  mainDocPart.Document.Body.Append(altChunk);
}

根据 Office OpenXML 规范,有效的父元素为 w:altChunk元素body, comment, docPartBody, endnote, footnote, ftr, hdr and tc .因此,我已将w:altChunk添加到正文元素中。

有关w:altChunk元素的详细信息,请参阅此 MSDN 链接。

编辑

正如@user2945722所指出的,为了确保 OpenXml 库的正确性将字节数组解释为 UTF-8,您应该添加 UTF-8 前导码。这可以通过以下方式完成:

MemoryStream ms = new MemoryStream(new UTF8Encoding(true).GetPreamble().Concat(Encoding.UTF8.GetBytes(htmlEncodedString)).ToArray()

这将防止您的 é 呈现为 Ã,您的 ä 呈现为 é¤,等等。

这里有同样的问题,但原因完全不同。如果接受的解决方案没有帮助,值得一试。尝试在保存后关闭文件。就我而言,它恰好是损坏和干净的docx文件之间的区别。奇怪的是,大多数其他操作只使用 Save(( 和程序出口。

String cid = "chunkid";
WordprocessingDocument document = WordprocessingDocument.Open("somefile.docx", true);
Body body = document.MainDocumentPart.Document.Body;
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("<html><head></head><body>hi</body></html>"));
AlternativeFormatImportPart formatImportPart = document.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, cid);
formatImportPart.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = cid;
document.MainDocumentPart.Document.Body.Append(altChunk);
document.MainDocumentPart.Document.Save();
// here's the magic!
document.Close();