一 什么是poi-tl
poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档*。
poi-tl官网地址:deepoove.com/poi-tl/
上手入门这里我就不写了 兄弟们有兴趣可以自己对照官方文档去敲几行。直接进入正文
导入依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.0</version>
</dependency>
- 我这里导入的是5.2.2版本的poi,springboot版本是3.0这里是可以兼容的,但是springboot2.2.0或者其他低版本的springboot这里log4j依赖不兼容。可以像下面一样排除引入的log依赖*
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>${poi-tl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j-api.version}</version>
</dependency>
编写controller
package com.example.wordpoitldemo.controller;
import com.deepoove.poi.XWPFTemplate;
import com.example.wordpoitldemo.WordService;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* @author: xh
* @date: 2023/11/15 9:48
*/
@Controller
@RequestMapping("/word")
public class WordController {
@Resource
private WordService wordService;
@ApiOperation("Download Word")
@GetMapping("download")
public void wordDownload( HttpServletResponse response) {
try {
XWPFTemplate document =wordService.generateWordXWPFTemplate();
String fileName="word文档导出.docx";
response.reset();
response.setContentType("text/html:charset=utf-8");
String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename="" + encodedFileName + """);
OutputStream os = response.getOutputStream();
document.write(os);
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
编写service
package com.example.wordpoitldemo;
import cn.hutool.core.collection.CollectionUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import com.example.wordpoitldemo.domain.WordModel;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: xh
* @date: 2023/11/15 10:14
*/
@Service
public class WordServiceImpl implements WordService{
/**
* 导出word模板
* @return
*/
@Override
public XWPFTemplate generateWordXWPFTemplate() {
//获取resources目录下的模板文件
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("word/template.docx");
// 在这里使用file进行操作,例如读取文件内容
XWPFTemplate template = XWPFTemplate.compile(inputStream);
WordModel wordModel=new WordModel();
wordModel.setName("张三");
wordModel.setAge("18");
wordModel.setSex("男");
wordModel.setHobbies("唱歌和打篮球");
//趋势图
String[] abscissaData={"01", "02","03","04","05","06","07","08","09","10",
"11","12","13","14","15","16","17","18","19","20",
"21","22","23","24","25","26","27","28","29","30"};
Double[] chargingCasesOrdinateData={
159309.69, 164566.38,156819.87,148378.92,123710.59,176014.0,154682.63,154635.78,154635.78,154635.78,
159309.69, 164566.38,156819.87,148378.92,123710.59,176014.0,154682.63,154635.78,154635.78,154635.78,
159309.69, 164566.38,156819.87,148378.92,123710.59,176014.0,154682.63,154635.78,154635.78,154635.78,
};
wordModel.setTrendChart(creatLineChart("当月收入折线图","日收入(RMB)",abscissaData,chargingCasesOrdinateData));
//表格
//科室开单排名(前十科室)
RowRenderData tenDepartmentsTableHead= Rows.of("排序", "科室名称","开单量").textColor("FFFFFF")
.bgColor("4472C4").center().create();
//创建表格list
List<RowRenderData> tenDepartmentsRowList=new ArrayList<>();
int order=1;
List<Map<String, Object>> tenDepartmentsTableDate = getTenDepartmentsTableDate();
if (CollectionUtil.isNotEmpty(tenDepartmentsTableDate)){
for (Map<String, Object> tenDepartments : tenDepartmentsTableDate) {
tenDepartmentsRowList.add(Rows.create(order+"",tenDepartments.get("departmentName")+"",tenDepartments.get("boldQuantity")+""));
order++;
}
}
wordModel.setTable(createTable(tenDepartmentsTableHead,tenDepartmentsRowList));
return template.render(wordModel);
}
/**
* 生成折线图
*
* @param title 图表标题
* @param name 当前系列名称
* @param abscissaData 横坐标数据
* @param ordinateData 纵坐标数据
* @return
*/
private ChartMultiSeriesRenderData creatLineChart(String title, String name, String[] abscissaData, Double[] ordinateData) {
ChartMultiSeriesRenderData chart = Charts
.ofLine3D(title, abscissaData)
.addSeries(name, ordinateData)
.create();
return chart;
}
/**
* 获取科室开单排名前十的数据
* @return
*/
private List<Map<String,Object>> getTenDepartmentsTableDate() {
List<Map<String,Object>> tenDepartmentsTableDate=new ArrayList<>();
Map<String,Object> map=new HashMap<>();
map.put("departmentName","测试1");
map.put("boldQuantity","50");
tenDepartmentsTableDate.add(map);
Map<String,Object> map1=new HashMap<>();
map1.put("departmentName","测试2");
map1.put("boldQuantity","500");
tenDepartmentsTableDate.add(map1);
return tenDepartmentsTableDate;
}
/**
*
* @param headRow 表头
* @param tableData 表格数据
* @return
*/
private TableRenderData createTable(RowRenderData headRow, List<RowRenderData> tableData) {
// 构造表格渲染数据 科室开单排名(前十科室)
TableRenderData table = Tables.of(headRow).center().create();
// 准备表格数据
if (CollectionUtil.isNotEmpty(tableData)){
for (RowRenderData renderData : tableData) {
table.addRow(renderData);
}
}
return table;
}
}
model类
package com.example.wordpoitldemo.domain;
import com.deepoove.poi.data.ChartMultiSeriesRenderData;
import com.deepoove.poi.data.TableRenderData;
import lombok.Data;
/**
* @author: xh
* @date: 2023/11/15 10:20
* word变量属性
*/
@Data
public class WordModel {
/**
* 单变量属性
*/
private String name;
private String age;
private String sex;
private String Hobbies;
/**
* 折线图
*/
private ChartMultiSeriesRenderData TrendChart;
/**
* 表格
*/
private TableRenderData table;
}
word模板设置
普通变量用{{}},表格变量用{{#}},折线图需要设置名称 我是用的wps 如下
到这里基本的一些讲解就结束了 最后看一下效果吧
这里只挑选了几种常见的word导出使用样例来展示,需要更多其他导出样例的 可以比照参考官方文档。
gitee:gitee.com/xianghaoddd…