使用 OpenXML 将 HTML 添加到 Word 但无法设置内容样式 (.Net Core)

Adding HTML to Word using OpenXML but unable to style the content (.Net Core)

我设法使用现有的 Word 文件将 HTML(仅文本)添加到此 post Add HTML String to OpenXML 之后的 Word 文档中。

不幸的是,我找不到任何解决方案来将此 Word 模板中的样式用于我新添加的文本。尽管使用的模板的标准样式是 "Arial" 大小 9px,但它总是 "Times New Roman" 大小 12px。

所以我试过了:

  1. 使用 ParagraphProperties,因为我不会 HTML 文本。
 Paragraph para = body.AppendChild(new Paragraph());
 Run run = para.AppendChild(new Run());
 run.AppendChild(altChunk);                           
 para.ParagraphProperties = new ParagraphProperties(new ParagraphStyleId() { Val = "berschrift2" });
  1. 关闭 MatchSource
 AltChunkProperties altChunkProperties = new AltChunkProperties();
 altChunkProperties.MatchSource = new MatchSource() { Val = new OnOffValue(false) };
 altChunk.AppendChild<AltChunkProperties>(altChunkProperties);

有什么建议吗?

编辑: 我找到了一个解决方法,它不是我的问题的真正解决方案,但对我有用。我不再尝试使用 word 中的样式,而是在使用 altchunk 之前将样式添加到我的 html 中。

您问题的真正解决方案是将 HTML 转换为 Open XML 标记 "yourself" 而不是依赖替代格式导入部分与 w:altChunk 元素结合使用.这会依赖于 Microsoft Word 处理导入的方式,而您通常几乎没有控制权。

如何将 HTML(或一般的 XML)转换为 Open XML 标记?最好的方法是编写所谓的递归纯函数转换,将 HTML 元素和属性转换为 Open XML 元素和属性。如果你有非常简单的 HTML 文件,那不是什么大事。然而,为 "arbitrary" HTML 和 CSS 做到这一点是一项了不起的壮举。

好消息是开源库 Open-XML-PowerTools 包含将 HTML 转换为 Open XML 的功能,反之亦然。因此,我建议您看看那个图书馆。

一些解释:如果您查看 ISO 29500-1 17.17.2.1 中 altChunk 的定义,特别是在 A.1 部分中,架构显示 altChunk 是一个 EG_BlockLevelElts 元素,这是一个与段落同行(即 )。将 child 添加到 运行 元素甚至段落在技术上是不正确的。它应该添加到 body 级别。 Word 在添加为 运行 或段落 child 时没有抱怨这一事实是无意的,不应依赖。

因此,Word 正在使用字体的默认样式 属性 来格式化此新内容。您可以通过更改 styles.xml 部分中的文档默认值来尝试此操作。将匹配源 属性 设置为 false,除了文档默认值外,没有其他方法可以指定字体。

话虽如此,我认为 Thomas 的替代方案是更好的选择。

对我和我的情况有用的方法(如果你不想使用相当复杂的 openxml powertools html 转换器根目录)是向正文添加 HTML 样式属性您的 HTML 片段部分如下:

Encoding.UTF8.GetBytes(
                @$"<html><head><title></title></head><body style=""font-family: Calibri"">{ConvertUnconventionalUnicodeCharsToAscii(htmlAsString)}</body></html>");

可以动态派生嵌入到您正在更新的文档中的“正常”样式的字体系列,如果认为兼容,则将该名称插入样式属性。

这样,如果您决定更改基本/普通字体,HTML 导入的样式将尝试使用相同的字体系列。

抱歉,如果有点跑题,我也无法让 alternativeFormatImportPart.FeedData() 处理“'”(代码 8217)UTF-16 字符,因此不得不专门用“'”(代码39) 为了避免它们被渲染成下面的序列 '