简介
poi-tl是一个基于Apache POI的开源Word模板引擎,比 Freemarker 的功能更加强大。
官方文档地址:http://deepoove.com/poi-tl/
导包
导入包时,依赖说明参考官方文档,导入包不适配可能会造成一些问题,此处可以使用
<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.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.6</version>
</dependency>
使用
所有的标签都是以{{
开头,以}}
结尾:{{title}}
,其余标签参考官方文档
区块对由前后两个标签组成,开始标签以?标识,结束标签以/标识:{{?sections}}{{/sections}}
区块对开始和结束标签中间可以包含多个图片、表格、段落、列表、图表等,开始和结束标签可以跨多个段落,也可以在同一个段落,但是如果在表格中使用区块对,开始和结束标签必须在同一个单元格内,因为跨多个单元格的渲染行为是未知的。
区块对在处理一系列文档元素的时候非常有用,位于区块对中的文档元素可以被渲染零次,一次或N次,这取决于区块对的取值。
- False或空集合:隐藏区块中的所有文档元素
- 非False且不是集合:显示区块中的文档元素,渲染一次
- 非空集合:根据集合的大小,循环渲染区块中的文档元素
数据类似于哈希或者字典,可以是Map结构(key是标签名称):
map:
Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");
entity:
public class Data {
private String name;
private String startTime;
private Author author;
}
以流的方式进行输出:
template.write(OutputStream stream);
// 文件流:
template.write(new FileOutputStream("output.docx"));
// 网络流:
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
表格
创建:
实现:
List<Users> list = new ArrayList<>(0);
data.put("users", list);
ConfigureBuilder builder = Configure.builder();
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
builder.bind("users", policy);
XWPFTemplate template = XWPFTemplate.compile(file.getPath(), builder.build()).render(data);
附件
可以直接在文档内打开,文档内保存了附件内容不是映射的本地地址
List<List<Objet>> users = new ArrayList<>(0);
for (int i = 0; i < 4; i++) {
List<Object> list = new ArrayList<>(0);
list.add("zhangsan");
list.add("zhangsan123");
list.add("pwd123");
list.add("2022-12-01 12:00:00");
}
List<Object> titles = Arrays.asList("用户名", "账号", "密码", "创建时间");
// 写入缓存文件
String url = "C:\\Users\\Public\\Documents\\users.xlsx";
File file = new File(url);
if (file.isFile()) {
file.delete();
}
ExcelWriter writer = ExcelUtil.getWriter(file);
writer.writeHeadRow(titles).write(users);
writer.flush().close();
removeUrls.add(url);
// 创建插件
AttachmentRenderData attach = Attachments.ofLocal(url, AttachmentType.XLSX).create();
data.put("users", attach);
AttachmentRenderPolicy attachmentRenderPolicy = new AttachmentRenderPolicy();
ConfigureBuilder builder = Configure.builder();
builder.bind("users", attachmentRenderPolicy);
// 获取模板文件
File fileTemplate = ResourceUtils.getFile("src/main/resources/templates/template.docx");
if (fileTemplate.exists()) {
XWPFTemplate template = XWPFTemplate.compile(fileTemplate.getPath(), builder.build()).render(data);
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=\"" + "out_template.docx" + "\"");
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
}
// 删除缓存的附件
if (file.isFile()) {
file.delete();
}
完整代码
private final String linuxUrl = "/home/";
private final String windowsUrl = "C:\\Users\\Public\\Documents\\";
/**
* 导出根据word模板生成
*/
@Override
public void exportDoc(HttpServletResponse response) throws IOException {
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String, Object> data = new HashMap<>(0);
data.put("time", time);
// 用户数据列表
List<User> users = new ArrayList<>(0);
for (int i = 0; i < 12; i++) {
User user = new User();
user.setUsername("zhangsan"+i);
user.setAccount("zhangsan"+i);
user.setPassword("12345"+i);
user.setCreateTime("2022-12-01 12:00:00");
users.add(user);
}
data.put("users", users);
if (users > 10) {
// 生成excel附件
List<List<Object>> usersExcels = new ArrayList<>(0);
for (int i = 0; i < users.size(); i++) {
List<Object> list = new ArrayList<>(0);
list.add(users.get(i).getUsername());
list.add(users.get(i).getAccount());
list.add(users.get(i).getPassword());
list.add(users.get(i).getCreateTime());
usersExcels.add(list);
}
List<Object> titles = Arrays.asList("用户名", "账号", "密码", "创建时间");
String url = this.downloadFileLocal("users.xlsx", titles, usersExcels);
removeUrls.add(url);
AttachmentRenderData attach = Attachments.ofLocal(url, AttachmentType.XLSX).create();
// 此时word文档内标签为{{usersExcels}}
data.put("usersExcels", attach);
}
File file = ResourceUtils.getFile("src/main/resources/templates/template.docx");
if (file.exists()) {
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
AttachmentRenderPolicy attachmentRenderPolicy = new AttachmentRenderPolicy();
ConfigureBuilder builder = Configure.builder();
builder.bind("users", policy);
builder.bind("usersExcels", attachmentRenderPolicy);
XWPFTemplate template = XWPFTemplate.compile(file.getPath(), builder.build()).render(data);
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=\"" + "out_template.docx" + "\"");
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
// 删除缓存的附件
this.deleteCacheFiles(removeUrls);
}
}
/**
* 生成excel附件
*
* @param fileName 文件名
* @param titles 表头
* @param data 数据
*/
private String downloadFileLocal(String fileName, List<Object> titles, List<List<Object>> data) throws IOException {
String url = "";
String osName = System.getProperty("os.name").toLowerCase();
if (Constants.isSystem(osName)) {
// Windows
url = windowsUrl + fileName;
} else {
// Linux
url = linuxUrl + fileName;
}
File file = new File(url);
if (file.isFile()) {
file.delete();
}
ExcelWriter writer = ExcelUtil.getWriter(file);
writer.writeHeadRow(titles).write(data);
writer.flush().close();
return url;
}
/**
* 删除缓存附件
*/
private boolean deleteCacheFiles(List<String> urls) {
for (String url : urls) {
File files = new File(url);
if (files.isFile()) {
files.delete();
}
}
return true;
}
标签:users,url,tl,template,poi,new,out,data,springboot
From: https://www.cnblogs.com/1399z3blog/p/17688439.html