Hidewnd Docs Hidewnd Docs
首页
  • 常用开发环境
  • 常用提示词
  • 常用Linux命令
  • Java开发聊天机器人
  • word模板生成实现方案
  • [学习笔记]Lua
  • [学习笔记]JVM
  • [学习笔记]设计模式
  • [部署笔记]搭建Typecho博客
  • [部署笔记]部署Qsign签名机
  • [部署笔记]安装PVE系统
  • [部署笔记]部署KingBaseV9电科金仓
  • 技艺成本
  • 剑三网站合集
  • 合并大区角色数据处理
  • 25PT冷龙峰教学笔记
  • 25PT太极宫教学笔记
关于
GitHub (opens new window)
首页
  • 常用开发环境
  • 常用提示词
  • 常用Linux命令
  • Java开发聊天机器人
  • word模板生成实现方案
  • [学习笔记]Lua
  • [学习笔记]JVM
  • [学习笔记]设计模式
  • [部署笔记]搭建Typecho博客
  • [部署笔记]部署Qsign签名机
  • [部署笔记]安装PVE系统
  • [部署笔记]部署KingBaseV9电科金仓
  • 技艺成本
  • 剑三网站合集
  • 合并大区角色数据处理
  • 25PT冷龙峰教学笔记
  • 25PT太极宫教学笔记
关于
GitHub (opens new window)
  • 常用开发环境
  • 常用提示词
  • 常用Linux命令
  • Java开发聊天机器人
  • word模板生成实现方案
    • 存在问题
    • 使用实例
    • 工具类封装
  • 文档
hidewnd
2025-08-24
目录

word模板生成实现方案

# word模板生成实现方案

传统word模板生成引擎主要采用FrameMark或Jasper构建模板文件并渲染生成;

# 存在问题

  1. 模板文件可读性差;
  2. 模板文件不可维护,开发人员模板修改及验证时间长;

优化方案:

替换采用poi-tlWord模板引擎,使用docx文件作为模板附件进行渲染及导出;降低模板文件维护难度,提高模板可读性;

poi-tl 基于Apache POI的Word模板引擎,项目免费开源,可商用;原生支持文本、图片、表格、列表、批注、EL表达式等;

poi-tl官网地址:https://deepoove.com/poi-tl/ (opens new window)

# 使用实例

核心依赖

poi低版本可使用低版本poi-tl,具体版本依赖关系可参考官网说明

  1. maven依赖

    
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    
    <dependency>
        <groupId>com.deepoove</groupId>
        <artifactId>poi-tl</artifactId>
        <version>1.12.2</version>
    </dependency>
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  2. 创建及编辑模板template.docx

    这是个word模板 参数name: {{name}}
    
    1
  3. 模板渲染及生成

      String templatePath = "C:\\Users\\Hidewnd\\Desktop\\template.docx";
      Map<String, Object> data = new HashMap<>();
      data.put("name", "Sayi");
      data.put("start_time", "2019-08-04");
      XWPFTemplate template = XWPFTemplate.compile(templatePath).render(data);
      String targetPath = "C:\\Users\\Hidewnd\\Desktop\\outputDocx.docx";
      template.writeAndClose(new FileOutputStream(targetPath));
    
    1
    2
    3
    4
    5
    6
    7

图片、表格、列表循环等可通过配置类Configure使用插件进行声明以实现不同效果

# 工具类封装

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * word模板生成工具类
 * <p>
 *     基于Poi-tl封装 官方文档:<a href="https://deepoove.com/poi-tl/">https://deepoove.com/poi-tl/</a>
 * </p>
 *
 * @author hidewnd
 */
public class WordExportUtils {


    /**
     * 根据模板文件导出文件
     *
     * @param templateFile 模板附件
     * @param targetName   目标文件名称
     * @param data         数据Map,包含模板中需要替换的数据
     * @return 生成文件对象
     * @throws Exception 可能抛出的异常
     */
    public static File exportByFile(File templateFile, String targetName, Map<String, Object> data) throws Exception {
        ConfigureBuilder builder = Configure.builder();
        return exportByFile(templateFile, targetName, data, builder.build());
    }

    /**
     * 根据模板文件导出文件
     *
     * @param templateFile 模板附件
     * @param targetName   目标文件名称
     * @param data         数据Map,包含模板中需要替换的数据
     * @param configure    配置参数项
     * @return 生成文件对象
     * @throws Exception 可能抛出的异常
     */
    public static File exportByFile(File templateFile, String targetName, Map<String, Object> data, Configure configure) throws Exception {
        checkTemplateFile(templateFile);
        File targetFile;
        try (XWPFTemplate template = XWPFTemplate.compile(templateFile, configure)) {
            template.render(data);
            String targetPath = formatTargetPath(templateFile.getParentFile().getAbsolutePath(), targetName);
            template.writeToFile(targetPath);
            targetFile = new File(targetPath);
        }
        return targetFile;
    }

    private static void checkTemplateFile(File templateFile) throws Exception {
        if (templateFile == null || !templateFile.exists() || !templateFile.isFile()) {
            throw new FileNotFoundException("template File not found.");
        }
        if (!FileUtil.getSuffix(templateFile).equals("docx")) {
            throw new RuntimeException("template file type must be docx.");
        }
    }

    private static String formatTargetPath(String targetParentPath, String targetName) {
        String fileName = StrUtil.emptyToDefault(targetName, "targetFile.docx");
        if (StrUtil.endWith(fileName, ".docx")) {
            fileName = StrUtil.replaceLast(fileName, ".doc", ".docx");
        }
        if (!fileName.contains(".docx")) {
            fileName += ".docx";
        }
        return targetParentPath + File.separator + fileName;
    }

    public static void exportByStream(InputStream templateStream, OutputStream outputStream, Map<String, Object> data) throws Exception {
        ConfigureBuilder builder = Configure.builder();
        exportByStream(templateStream, outputStream, data, builder.build());
    }

    public static void exportByStream(InputStream templateStream, OutputStream outputStream,
                                    Map<String, Object> data, Configure configure) throws Exception {
        try (XWPFTemplate template = XWPFTemplate.compile(templateStream, configure)) {
            template.render(data);
            template.write(outputStream);
        }
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
帮助我改善此页面 (opens new window)
上次更新: 2025/08/25, 15:55:52
Java开发聊天机器人

← Java开发聊天机器人

Theme by Vdoing | Copyright © 2024-2025 Hidewnd
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式