You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用docx4j将docx模板中未赋值的变量设为空字符串?

问题

我在.docx文档中用${<变量名>}格式定义了若干变量,通过docx4j的VariablePrepare.prepare(doc)和document.getMainDocumentPart().variableReplace(placeholders)方法,结合Map数据替换变量。但如果Map中缺少部分变量,替换后的文档会直接显示变量名称,而非空字符串。

现有代码如下:

VariablePrepare.prepare(document);
val placeholders = new HashMap<>(PLACEHOLDERS_STATIC);
if (data != null) {
    final HashMap<String, String> dynamicPlaceholders = new HashMap<>() {{
            put("firstName", "First name");
            put("firstNameVal", data.getFirstName());
            put("childTable", "Child");
            put("lastName", "Last name");
    }};
    placeholders.putAll(dynamicPlaceholders);
    document.getMainDocumentPart().variableReplace(placeholders);
}

模板效果:
模板截图

替换后效果:
替换后截图

我希望未填充的变量显示为空字符串而非变量名,能否通过docx4j实现?手动给大量文档的所有变量设置空值过于耗时。

当前依赖:

<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
    <version>11.4.9</version>
</dependency>

解决方案

方法1:自动补全缺失变量为空值

先从docx模板中提取所有定义的变量,再将Map中不存在的变量自动设为空字符串,无需手动维护:

  1. 提取模板中所有${xxx}格式的变量名;
  2. 遍历变量列表,为Map中缺失的变量添加空值映射;
  3. 执行默认的变量替换方法。

示例代码:

// 1. 提取模板中的所有变量
List<String> allVariables = extractAllVariables(document);
// 2. 补全缺失变量为空值
for (String var : allVariables) {
    placeholders.putIfAbsent(var, "");
}
// 3. 执行替换
document.getMainDocumentPart().variableReplace(placeholders);

// 提取变量的工具方法
private List<String> extractAllVariables(WordprocessingMLPackage doc) throws Exception {
    List<String> variables = new ArrayList<>();
    Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
    // 遍历文档所有段落
    List<P> paragraphs = doc.getMainDocumentPart().getContents().getBody().getP();
    for (P p : paragraphs) {
        String text = XmlUtils.unwrap(p).toString();
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            variables.add(matcher.group(1));
        }
    }
    // 去重后返回
    return new ArrayList<>(new HashSet<>(variables));
}

方法2:自定义变量替换逻辑

绕过docx4j默认的variableReplace方法,直接遍历文档文本节点,对未匹配到的变量直接替换为空字符串:

示例代码:

// 自定义变量替换方法
public void replaceVariables(WordprocessingMLPackage doc, Map<String, String> placeholders) throws Exception {
    VariablePrepare.prepare(doc);
    Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
    // 遍历文档中所有文本节点
    List<Object> textNodes = doc.getMainDocumentPart().getJAXBNodesViaXPath("//w:t", false);
    for (Object node : textNodes) {
        Text text = (Text) node;
        String content = text.getValue();
        Matcher matcher = pattern.matcher(content);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String varName = matcher.group(1);
            // 变量不存在则替换为空字符串
            String replacement = placeholders.getOrDefault(varName, "");
            matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
        }
        matcher.appendTail(sb);
        text.setValue(sb.toString());
    }
}

// 使用自定义方法替换变量
replaceVariables(document, placeholders);

内容的提问来源于stack exchange,提问作者MarekChr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:53:18