Java根据word模板生成word文件
1.简介
处理word的方式有许多种:
- 使用Hutool工具类,但是只能处理简单的word,不能处理表格,动态图片,替换文字等
- 使用Apache POI,可以处理复杂的Word文档,但是处理过程复杂,word转xml,xml再转ftl才可进行操作,不适合经常处理word
- 其他第三方工具
- XDocReport +FreeMarker,该技术组合既简单又高效可实现word模板的编辑,只可处理docx文件
本文将实现动态文本替换、动态图片替换、动态表格填充。
2.pom引入
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.core</artifactId><version>2.0.2</version>
</dependency>
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document</artifactId><version>2.0.2</version>
</dependency>
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template</artifactId><version>2.0.2</version>
</dependency>
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document.docx</artifactId><version>2.0.2</version>
</dependency>
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId><version>2.0.2</version>
</dependency>
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version>
</dependency>
3.动态文本替换
比如说我们有个邮件word模板,需要动态的在横线处填入相关信息,然后生成完整的word文档。
我们做以下操作:
- 将横线位置替换成域
- 给每个要替换的位置取个名字
- FreeMarker域格式为—— ${……},具体操作可以查看视频模板添加域示例(下面添加域方法同理)
代码实现
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;/*** @author: YSL* @date: 2022/8/2 17:42*/
public class WordTemplate {private static final Logger logger = LoggerFactory.getLogger(WordTemplate.class);public static void test() {InputStream ins = null;OutputStream out = null;try {//获取Word模板,模板存放路径ins = new FileInputStream("C:\\Users\\she52\\Desktop\\演示.docx");//注册xdocreport实例并加载FreeMarker模板引擎IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);//创建xdocreport上下文对象,用于存放具体数据IContext context = report.createContext();//创建要替换的文本变量context.put("name", "李梅");context.put("sendName", "张三");context.put("year", "2022");context.put("month", "08");context.put("day", "03");//输出到本地目录String filePath = "C:\\Users\\she52\\Desktop\\结果.docx";out = new FileOutputStream(new File(filePath));report.process(context, out);} catch (Exception e) {logger.info("生成word发生异常", e);} finally {try {if (ins != null){ins.close();}if (out != null){out.close();}} catch (IOException e) {logger.info("文件流关闭失败", e);}}}
}
注意,执行代码时要把word模板关掉,否则模板加载不成功,会报错
执行结果:
4.动态表格
如果表格是标准的几行几列的列表,使用以下方法。如果不是标准的,比如说合并单元格,则需要使用上 面文本替换的方法,挨个起名赋值。
我们做以下操作:
- 除了标题行,保留一行空白行,删掉其余的空白行(为什么这么做,因为表格填充,本质是列表循环填写,列表大小是不确定的,我们只保留一行,让它自己根据列表大小创建行数)
- 起一个列表名,比如上面的示例表是用户信息表,则起名为userInfo
- 对用户信息属性挨个起名,姓名name、年龄age、性别sex
- 第2和第3步骤,等同于新建一个Java实体类
- 添加域,命名规范-----userInfo.name、{userInfo.name}、userInfo.name、{userInfo.age}、${userInfo.sex},自己总结规律
- 修改完后记得保存,然后关闭word
代码实现:
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;/*** @author: YSL* @date: 2022/8/2 17:42*/
public class WordTemplate {private static final Logger logger = LoggerFactory.getLogger(WordTemplate.class);public static void test() {InputStream ins = null;OutputStream out = null;try {//获取Word模板,模板存放路径ins = new FileInputStream("C:\\Users\\she52\\Desktop\\演示.docx");//注册xdocreport实例并加载FreeMarker模板引擎IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);//创建xdocreport上下文对象,用于存放具体数据IContext context = report.createContext();//创建要替换的文本变量List<UserInfo> userInfos = new ArrayList<>();UserInfo userInfo = new UserInfo();userInfo.setName("张三");userInfo.setAge("15");userInfo.setSex("男");userInfos.add(userInfo);UserInfo userInfo1 = new UserInfo();userInfo1.setName("李四");userInfo1.setAge("14");userInfo1.setSex("男");userInfos.add(userInfo1);UserInfo userInfo2 = new UserInfo();userInfo2.setName("李梅");userInfo2.setAge("16");userInfo2.setSex("女");userInfos.add(userInfo2);//此处的userInfo是word中命名的列表名context.put("userInfo", userInfos);//创建字段元数据FieldsMetadata fm = report.createFieldsMetadata();//Word模板中的表格数据对应的集合类型fm.load("userInfo", UserInfo.class, true);//输出到本地目录String filePath = "C:\\Users\\she52\\Desktop\\结果.docx";out = new FileOutputStream(new File(filePath));report.process(context, out);} catch (Exception e) {logger.info("生成word发生异常", e);}finally {try {if (ins != null){ins.close();}if (out != null){out.close();}} catch (IOException e) {logger.info("文件流关闭失败", e);}}}
}@Data
public class UserInfo{private String name;private String age;private String sex;
}
执行结果
注意,代码中创建的UserInfo实体类必须是public公共的,否则赋不到值
5.动态图片
比如说word文档中有,勾选框, 同意则打对勾。我们可以将勾选框变成图片,再令准备一张打好对勾的图片,如果勾选则将其替换,否则不替换,就可以完美解决勾选问题。
做以下操作:
- 将勾选的圆圈替换成大小相同的图片,可以让UI帮忙整一个
- 给图片添加标签并命名,直接写名字就行,不用加${}
代码实现:
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.ByteArrayImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;/*** @author: YSL* @date: 2022/8/2 17:42*/
public class WordTemplate {private static final Logger logger = LoggerFactory.getLogger(WordTemplate.class);public static void test() {InputStream in = null;OutputStream out = null;FileInputStream fins = null;try {//获取Word模板,模板存放路径in = new FileInputStream("C:\\Users\\she52\\Desktop\\演示.docx");//注册xdocreport实例并加载FreeMarker模板引擎IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);//创建xdocreport上下文对象,用于存放具体数据IContext context = report.createContext();//图片元数据FieldsMetadata metadata = report.createFieldsMetadata();//读取对勾圆形图片fins = new FileInputStream(new File("C:\Users\she52\Desktop\hookRound.png"));metadata.addFieldAsImage("accept");//只在同意上打对勾,不同意那个图片则不用管context.put("accept", new ByteArrayImageProvider(fins));report.setFieldsMetadata(metadata);//输出到本地目录String filePath = "C:\\Users\\she52\\Desktop\\结果.docx";out = new FileOutputStream(new File(filePath));report.process(context, out);} catch (Exception e) {logger.info("生成word发生异常", e);}finally {try {if (in != null){in.close();}if(fins != null){fins.close();}if(out != null){out.close();}} catch (IOException e) {logger.info("文件流关闭失败",e);}}}
}
运行结果:
注意
读取图片大多人用IImageProvider image = FileImageProvider(new File(……));但是这种方式,文件流不能关闭,所以用ByteArrayImageProvider(new FileInputStream())可及时关闭InputStream流。
如果word有多个地方需要不同的动态图片,可以挨个对图片添加书签并命名,然后重复以下代码
fins = new FileInputStream(new File("C:\Users\she52\Desktop\image1.png"));
metadata.addFieldAsImage("image1");
context.put("image1", new ByteArrayImageProvider(fins));
6.总结
如果Word模板文件复杂,则融合上面三种方法,即可满足绝大部分需求,如果满足不了,百度吧__。
Java根据word模板生成word文件相关推荐
- java 根据word模板生成word文件
Java可以使用Apache POI库来生成Word文件,并且也可以使用freemarker等模板引擎来实现根据Word模板生成Word文件的功能. 下面是一个简单的示例代码,可以帮助您快速入门. 模 ...
- apache poi使用例_使用java Apache poi 根据word模板生成word报表例子
[实例简介] 使用java Apache poi 根据word模板生成word报表 仅支持docx格式的word文件,大概是word2010及以后版本,doc格式不支持. 使用说明:https://b ...
- JAVA实现模板word文档导入,Java依据word模板生成word文档之后台解析和实现及部分代码(一)...
Java根据word模板生成word文档之后台解析和实现及部分代码(一) 后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换. ...
- 使用java Apache poi 根据word模板生成word报表
使用java Apache poi 根据word模板生成word报表 使用poi读取word模板,替换word中的{text}标签,并根据自定义标签循环生成表格或表格中的行. 代码示例下载:https ...
- 根据word模板生成word和PDF
根据word模板生成word和PDF 需求:有一个固定的合同模板,在vue前台填写指定的信息,替换合同模板指定的内容 我们使用的默认模板内容如图: 我们在前端填写的字段就是合同名称.项目名称和项目金额 ...
- word模板生成word报表文档
主要功能为根据word模板生成word报表文档,注意引用Interop.Word.dll; 首先要生成word程序对象 Word.Application app = new Word.Applicat ...
- C#根据word模板生成word表格报表文档
主要功能为根据word模板生成word报表文档,注意引用Interop.Word.dll; 首先要生成word程序对象 Word.Application app = new Word.Applicat ...
- 使用word模板生成word文档的各类方案
使用word模板生成word文档的各类方案 生成word的各种方案 word另存xml进行后续处理 2003版本word(.doc)的xml处理并生成word 2007版本word(.docx)的xm ...
- PHP 使用word模板生成word文档示例
<?php namespace Home\Controller; use PhpOffice\PhpWord\TemplateProcessor; use Think\Controller; c ...
- java手动/按模板生成word与excel
目录 一.前言 二.生成word 1.使用Apache poi手动生成一个word (1)导入依赖 (2)手动生成一个包含表格的word 2.使用Apache poi 按模板生成一个简单的word ( ...
最新文章
- 200万!这所“双一流”也开始高薪抢人了!
- RabbitMQ 消费端限流、TTL、死信队列
- 【Android 逆向】Android 进程注入工具开发 ( 编译注入工具 | 编译结果文件说明 | 注入过程说明 )
- CloudStack无法添加模板和iso
- linux搭建web服务器原理,【LINUX】linux搭建web服务器
- 【Linux】kali 2019.4 安装中文输入法
- 再接再厉!Alphabet将携手更多汽车厂商测试无人驾驶
- opencv 调整图像亮度和对比度
- panel items 添加指定位置_通过gitlab-ci自动添加prometheus业务监控
- macbook加入路由_笔记本怎么安装无线路由器 MacBook安装无线路由器方法【详细步骤】...
- VUE实现市、区二级联动
- 天猫精灵通过私有云控制WiFi设备
- Android 实现远程控制(类似QQ的远程协助)
- autoJS 网易公开课app封装函数
- ubuntu服务器安装及网络配置
- android设备控制机器人,基于Android手机的六足机器人控制方案的设计与实现
- 自定义Maven Archetype模板工程
- Linux下shell命令:top
- python基于django的商品比价平台
- 关于SEGGER和Jlink下载的问题