使用DOCX4J嵌入HTML为altchunk时,修复docx内联字体大小异常
使用docx4j嵌入HTML AltChunk时H1标签24pt字体大小失效的问题
问题现象
通过docx4j生成DOCX文件时,将HTML字符串以AltChunk形式嵌入,出现以下异常:
- H1标签内联style设置
font-size:24pt时,在MS Word中显示为14pt,未按预期生效; - 设置23pt或25pt时,字体大小显示正常;
- P标签、H2等其他标题标签无此问题。
示例HTML
"<html><body><h1 style="font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 24pt;">H1</h1><h2 style="font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 26pt;"> H2 </h2></body></html>"
代码示例
String html = "<html><body><h1 style=\"font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 24pt;\">H1</h1><h2 style=\"font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 26pt;\"> H2 </h2></body></html>"; WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(); byte[] bytes = html.getBytes(StandardCharsets.UTF_8); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); wordMLPackage.getMainDocumentPart().addAltChunk(AltChunkType.Html, bais); ByteArrayOutputStream baos = new ByteArrayOutputStream(); wordMLPackage.save(baos); byte[] docxFile = baos.toByteArray();
问题原因
MS Word在解析HTML AltChunk时,会自动将H1-H6标签映射到对应的内置段落样式(如Heading 1)。当HTML内联样式的字体大小与内置样式的默认值或Word解析引擎的特定阈值冲突时,内置样式会覆盖内联样式,导致24pt的设置被忽略,显示为内置Heading 1样式的14pt。
解决方案
方案1:给内联样式添加!important强制优先级
修改H1标签的style属性,为font-size添加!important,强制覆盖内置样式:
<h1 style="font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 24pt !important;">H1</h1>
方案2:修改文档内置Heading 1样式
通过docx4j预先修改文档的内置Heading 1样式,使其字体大小为24pt,再嵌入AltChunk:
// 获取内置Heading 1样式 Style heading1Style = wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart().getStyleById("Heading1"); if (heading1Style != null) { RPr rPr = heading1Style.getRPr(); if (rPr == null) { rPr = new ObjectFactory().createRPr(); heading1Style.setRPr(rPr); } // Word中字体大小以半磅为单位,24pt对应48 Sz sz = new ObjectFactory().createSz(); sz.setVal(BigInteger.valueOf(48)); rPr.setSz(sz); SzCs szCs = new ObjectFactory().createSzCs(); szCs.setVal(BigInteger.valueOf(48)); rPr.setSzCs(szCs); } // 后续添加AltChunk逻辑不变
方案3:替换H1标签为P标签
将H1标签替换为P标签,避免触发Word的内置标题样式映射,直接使用内联样式:
<p style="font-weight: normal; line-height: 1.1; margin-top: 0.2em; margin-bottom: 0.2em; background-color: transparent; color: #404040; font-family: Calibri; font-size: 24pt;">H1</p>
内容的提问来源于stack exchange,提问作者mogli5
相关产品推荐
相关产品推荐

