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

相关推荐
0x00073 分钟前
译 Anders Hejlsberg 谈 C# 与 .NET
开发语言·c#·.net
梓色系4 分钟前
Spring AI 实战:从零搭建 MCP 客户端与服务端,让大模型拥有“手脚“
java·人工智能·spring
秦时星星13 分钟前
Spring AI + FastMCP 跨语言集成踩坑实录
java·人工智能·spring
见牛羊15 分钟前
docker理解
java·docker·容器
codingPower19 分钟前
JAVA后端安全进阶:基于HMAC-SHA256+Nonce+Timestamp的API防重放攻击方案
java·开发语言·spring boot·安全
Xin_ye1008622 分钟前
C# 零基础到精通教程 - 第十七章:前端集成——Blazor 基础
开发语言·c#
寂夜了无痕24 分钟前
IntelliJ IDEA 高效配置:新建文件自动生成作者与时间注释
java·ide·intellij-idea
daopuyun32 分钟前
《C#语言源代码漏洞测试规范》解读,如何依据GB/T 34946-2017标准建立代码测试技术体系
c#·代码测试·源代码安全检测
leonidZhao33 分钟前
Java 25新特性:模块导入申明
java
weixin_489690021 小时前
【IDEA 2025.2.4】 Maven 仅能手动 Reload All Maven Projects 问题解决
java·maven·intellij-idea