通过java后端代码来实现给word内容补充格式文本内容控件,以及 设置控件的标记和标题

1. 准备工作:添加 docx4j 依赖

pom.xml 中加入(以 8.2.9 版本为例,支持 JAXB 自带实现,避免 JDK 9+ 的模块问题):

xml 复制代码
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j</artifactId>
    <version>8.2.9</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

若使用 Spring Boot 项目且 JDK 版本较高,docx4j 8.2.9 会自动引入合适的 JAXB 实现,通常只需上面两个依赖。


2. 核心代码:创建一个带标记和标题的内容控件

下面的方法会创建一个新的空白 Word 文档,并在其中插入一个格式文本内容控件 (SdtBlock) ,同时设置 Tag 和 Title(代码中通过 SdtPr.Alias 对应 Word 的标题字段)。

java 复制代码
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;

import java.io.File;

public class CreateSdtBlockExample {

    public static void main(String[] args) throws Exception {
        // 1. 创建空白 docx 包
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
        MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();

        // 2. 创建一个格式文本内容控件 SdtBlock
        SdtBlock sdtBlock = createRichTextSdtBlock("REF_QUAL_001", "资格条件内容区域");

        // 3. 将控件添加到文档主体
        mainDocumentPart.getContent().add(sdtBlock);

        // 4. 保存文件
        wordMLPackage.save(new File("output_with_sdt.docx"));
        System.out.println("文档已生成:output_with_sdt.docx");
    }

    /**
     * 构建一个带 Tag 和 Title(Alias)的富文本内容控件
     * @param tagValue   标记(对应 Word 属性中的"标记")
     * @param titleValue 标题(对应 Word 属性中的"标题")
     * @return SdtBlock 对象
     */
    private static SdtBlock createRichTextSdtBlock(String tagValue, String titleValue) {
        ObjectFactory factory = new ObjectFactory();

        // -------- 构建控件属性 <w:sdtPr> --------
        SdtPr sdtPr = factory.createSdtPr();

        // 设置 Tag(<w:tag w:val="..."/>)
        Tag tag = factory.createTag();
        tag.setVal(tagValue);
        sdtPr.getRPrOrAliasOrLock().add(tag);

        // 设置 Title,在 docx4j 中用 SdtPr.Alias 对应 <w:alias w:val="..."/>
        SdtPr.Alias alias = factory.createSdtPrAlias();
        alias.setVal(titleValue);
        sdtPr.getRPrOrAliasOrLock().add(alias);

        // 可选:设置控件为富文本类型(place holder 等),这里保持默认即可

        // -------- 构建控件内容 <w:sdtContent> --------
        SdtContentBlock sdtContent = factory.createSdtContentBlock();

        // 在控件内放一个占位段落
        P paragraph = factory.createP();
        R run = factory.createR();
        Text text = factory.createText();
        text.setValue("请在此输入内容...");
        run.getContent().add(text);
        paragraph.getContent().add(run);
        sdtContent.getContent().add(paragraph);

        // -------- 组装 SdtBlock --------
        SdtBlock sdtBlock = factory.createSdtBlock();
        sdtBlock.setSdtPr(sdtPr);
        sdtBlock.setSdtContent(sdtContent);

        return sdtBlock;
    }
}

代码对应关系

Word 界面操作 docx4j 代码实现
开发工具 → 格式文本内容控件 创建 SdtBlock 对象
选中控件 → 属性 → 标记(Tag) Tag tag = factory.createTag(); tag.setVal("ID"); 放入 SdtPr
选中控件 → 属性 → 标题(Title) SdtPr.Alias alias = factory.createSdtPrAlias(); alias.setVal("标题"); 放入 SdtPr
控件内的提示文字 SdtContentBlock 中添加一个 P(段落),内含 RText

3. 向现有文档追加内容控件

如果你的场景是基于已有模板动态插入控件,只需加载现有文件,然后添加到 mainDocumentPart.getContent() 即可:

java 复制代码
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File("template.docx"));
MainDocumentPart mainPart = wordMLPackage.getMainDocumentPart();

SdtBlock newSdt = createRichTextSdtBlock("REF_EVAL_005", "评标办法区");
mainPart.getContent().add(newSdt);   // 追加到末尾(或按需插入指定位置)

wordMLPackage.save(new File("template_with_sdt.docx"));

4. 两个容易混淆的属性说明

  • Tag(标记) :在 OOXML 中对应 <w:tag w:val="xxx"/>,是程序识别控件的主要标识,你的 SdtBlockUtils 正是通过它来查找控件。
  • Title(标题) :在 OOXML 中对应 <w:alias w:val="xxx"/>(docx4j 中用 SdtPr.Alias 表示),也就是 Word 属性对话框中的"标题"输入框。它更多用于界面提示,也可作为备用标识。

代码中 getSdtBlockAlias 读取的就是这个 Alias 值。


5. 注意事项

  1. JAXB 兼容性 :如果运行时报 JAXB 相关错误,请检查依赖是否完整。使用 docx4j 8.2.9 以上版本一般可以自动处理,但你也可尝试 org.docx4j:docx4j-JAXB-ReferenceImpl 等预绑定包。
  2. 控件的默认样式 :新创建的 SdtBlock 使用的字体、缩进等会继承文档默认样式,你可以通过添加 PPr / RPr 进一步设置。
  3. 生产环境建议:你的示例工具类中已经有很好的异常降级机制,这部分创建控件的逻辑也可以整合进去,作为生成模板模块的一部分。

这样,就完全用 Java 实现了"给 Word 补充内容控件并设置标记和标题"的全过程。生成的 docx 文件再用 SdtBlockUtils 去填充内容,就形成了一套完整的自动化文档流水线。

相关推荐
無限進步D2 小时前
Java 面向对象高级 接口
java·开发语言
逸Y 仙X2 小时前
文章二十七:ElasticSearch ES查询模板(Search Template)高效复用实战
java·大数据·数据库·elasticsearch·搜索引擎·全文检索
二哈赛车手3 小时前
新人笔记---Spring AI的Advisor以及其底层机制讲解(涉及源码),包含一些遇见的Spring AI的Advisor缺陷问题的解决方案
java·人工智能·spring boot·笔记·spring
AC赳赳老秦3 小时前
接口测试自动化:用 OpenClaw 对接 Postman,实现批量回归测试、测试报告自动生成与推送
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
两年半的个人练习生^_^3 小时前
Java日志框架和使用、日志记录规范
java·开发语言·开发规范
pq2173 小时前
最简单的理解synchronized锁升级
java
杨凯凡3 小时前
【032】排查入门:jstack、heap dump、Arthas 初识
java·开发语言·后端
pq2173 小时前
Spring FactoryBean源码解析
java·spring boot·spring