通过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(段落),内含 R 和 Text

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 去填充内容,就形成了一套完整的自动化文档流水线。

相关推荐
EatFan2 小时前
Spring Boot 4 落地观察:从 yudao-cloud、matecloud、JPower 看国产脚手架的升级路线与迁移清单
java·spring boot·后端·spring cloud·微服务·后端开发·jdk 21
Maiko Star3 小时前
* LangChain 提示词模板详解:ChatPromptTemplate 的使用与高级特性
java·人工智能·langchain
波力海苔夹心脆6754 小时前
C# 序列化与反序列化详解:System.Text.Json、Newtonsoft.Json、XmlSerializer 用法、特性选项与安全实践
经验分享·后端·c#·json·.net
现任明教教主~5 小时前
Thinkphp站群蜘蛛池SaaS系统YanyvSEO含多用户/积分/六大引擎计费/易支付对接
java·开发语言·spring
一条破秋裤6 小时前
Linux 线程创建:pthread_create 与基本回收
java·linux·运维
布吉岛的石头6 小时前
Java 程序员第 49 阶段5:BERT 预训练目标 MLM+NSP 的工程含义
java·人工智能·深度学习·bert·transformer
摇滚侠7 小时前
《On Java 中文版 基础卷》阅读笔记 对象无处不在 03
java·笔记·python
二十雨辰7 小时前
[学成在线]-01项目背景
java
弈栈录8 小时前
Java AI 应用的异步化与高并发设计
java·后端·架构
落魄实习生8 小时前
Agent Scope Java 2.x 系列【2】 ReActAgent
java·开发语言