Docx4j执行variableReplace时如何为替换内容设置加粗、高亮样式
docx4j 自带的 variableReplace 方法仅支持纯文本替换,无法为不同变量单独设置样式,你可以修改实现逻辑,手动遍历文本节点匹配占位符、设置对应样式后再替换内容,完整实现代码如下:
import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.docx4j.wml.*; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.HashMap; import java.util.List; public class DocxTemplateUtils { public byte[] generateDocx(InputStream templateInputStream) throws Exception { WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(templateInputStream); MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart(); // 先合并拆分的变量占位符,避免变量分散到多个Run节点 VariablePrepare.prepare(wordMLPackage); // 变量配置 HashMap<String, String> variables = new HashMap<>(); variables.put("firstName", "fileName123"); variables.put("lastName", "lastName345"); variables.put("message", "messsssssss"); // 遍历文档所有段落 List<Object> paragraphs = documentPart.getContent(); for (Object p : paragraphs) { if (p instanceof P) { List<Object> runs = ((P) p).getContent(); for (Object r : runs) { if (r instanceof R) { R run = (R) r; List<Text> textList = run.getContent().stream() .filter(c -> c instanceof Text) .map(c -> (Text) c) .toList(); for (Text text : textList) { String content = text.getValue(); // 匹配变量占位符 if (content.startsWith("${") && content.endsWith("}")) { String varName = content.substring(2, content.length() - 1); String replaceValue = variables.get(varName); if (replaceValue == null) { continue; } // 初始化样式节点 RPr rPr = run.getRPr() == null ? new RPr() : run.getRPr(); run.setRPr(rPr); // 给不同变量设置对应样式 if ("firstName".equals(varName)) { // 设置加粗 rPr.setB(new BooleanDefaultTrue()); } else if ("message".equals(varName)) { // 设置黄色高亮 Highlight highlight = new Highlight(); highlight.setVal("yellow"); rPr.setHighlight(highlight); } // 替换文本内容 text.setValue(replaceValue); } } } } } } ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); wordMLPackage.save(outputStream); return outputStream.toByteArray(); } }
核心逻辑说明:
- 调用
VariablePrepare.prepare方法预先合并分散到多个文本节点的变量占位符,避免漏匹配 - 上述代码默认遍历文档顶层段落的文本块,识别
${变量名}格式的占位符,如果你的变量放在表格、页眉页脚中,额外扩展遍历对应节点的内容即可,逻辑完全一致 - 匹配到目标变量后,先给文本块设置对应样式,再替换文本内容
- 普通变量无样式需求的话,直接替换即可
内容的提问来源于stack exchange,提问作者Dogrammer
相关产品推荐
相关产品推荐

