在日常的开发中,使用后台技术生成word文档的需求是非常常见,例如根据数据,生成汇报的word文档。word文档的本质其实是xml。因此我们可以基于这个特性,使用java模版技术(Beetl、freemark等等)进行动态word文档生成。
word文档动态生成,核心在于以下两点:
- 文本内容替换
- 图片替换
基于这两点,我们就可以根据已有的模版,进行动态word生成,下面就以Beetl模版技术来实现此效果。
1. 新建一个maven工程,项目的pom.xml依赖如下:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.7</version>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>2.7.23</version>
</dependency>
</dependencies>
2. 新建一个word文档,并写下简单的内容,如下图:

我们写好内容后,在word中,点击文件菜单->另存为,选择保存格式为word xml文档。随后,我们就得到了一个xml文件,如下图

我们打开这个xml文件,可以看到一堆xml文件代码,但是,我们只用关注两点。
- 图片内容(包裹在<pkg:binaryData></pkg:binaryData>)

可以看到如上的内容,上面的内容,即图片base64编码后的内容。我们可以通过后端代码,生成图片的base64代码后,替换此块区域。我们现在使用${image}来替换xml中的base64编码图片
- 文字内容。

如上图,我们发现在xml中,有时候会把我们的一个占位值进行分离了,因此,我们在生成xml后,还需要手动检查以下,看下是否有以上问题,有的话,就修改,添加缺少的,删除多余的。
下面我们就开始进行代码编写,如下:
public static void main(String[] args) {
// 读取模版内容
File templateFile = new ClassPathResource("HelloWord.xml").getFile();
String content = FileUtil.readString(templateFile, Charset.forName("UTF-8"));
// 模版工具初始化
StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
Configuration cfg = null;
try {
cfg = Configuration.defaultConfiguration();
} catch (IOException e) {
e.printStackTrace();
}
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
//设置模板
Template t = gt.getTemplate(content);
// 读取图片与生成base64
File imageFile = new ClassPathResource("demo.png").getFile();
String encode = Base64.encode(imageFile);
//配置参数
t.binding("title", "Hello word template");
t.binding("image",encode);
FileUtil.writeString(t.render(),"~/DemoWord.docx",Charset.forName("UTF-8"));
}
生成的效果如下图所示:

至此,使用模版技术动态生成word文档就已经完成,在实际应用中,可以根据自己的业务需要,调整模版。