使用deepoove根据模板导出word文档,包括文本、表格、图表、图片,使用WordConvertPdf可将word文档转换为pdf导出
模板样例:
![](https://file.jishuzhan.net/article/1711359276720590850/535a4ba7baadb02a7b5b5ba08b925d66.webp)
导出结果:
![](https://file.jishuzhan.net/article/1711359276720590850/37a90993d490609a92e183c645d11aa6.webp)
一、引入相关依赖
XML
<!-- 工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- poi-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.11.1</version>
</dependency>
<!-- word转pdf-->
<dependency>
<groupId>WordConvertPdf</groupId>
<artifactId>WordConvertPdf</artifactId>
<version>1.0</version>
</dependency>
二、创建导出数据实体类
java
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value = "ExportVO", description = "导出VO")
public class ExportVO {
@ApiModelProperty(value = "标题")
private String title;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "数量")
private Integer num;
@ApiModelProperty(value = "集合数据")
private List<ExportListVO> list;
@ApiModelProperty(value = "表格")
private List<ExportListVO> table;
@ApiModelProperty(value = "柱状图")
private ChartMultiSeriesRenderData barChart;
@ApiModelProperty(value = "饼图")
private ChartSingleSeriesRenderData pieChart;
@ApiModelProperty(value = "折线图")
private ChartMultiSeriesRenderData lineChart;
@ApiModelProperty(value = "图片")
private PictureRenderData img;
}
java
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value = "ExportListVO", description = "导出集合VO")
public class ExportListVO {
@ApiModelProperty(value = "类型")
private String type;
@ApiModelProperty(value = "数量")
private Integer num;
}
三、业务代码
java
/**
* 文档导出
*
* @param fileType 导出文件类型:1-docx,2-pdf
* @param response 响应流
*/
@Override
public void exportFile(Integer fileType, HttpServletResponse response) throws IOException {
//模板地址,存放在resources目录下
String filePath = "templates/word/test.docx";
//使用poi-tl进行模板处理
ConfigureBuilder builder = Configure.builder();
builder.useSpringEL(true);
//执行循环策略
LoopRowTableRenderPolicy strategy = new LoopRowTableRenderPolicy();
//绑定集合对象
builder.bind("list", strategy);
builder.bind("table", strategy);
//获取模板文件流
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
assert inputStream != null;
//组装数据
ExportVO data = this.createData();
XWPFTemplate render = XWPFTemplate.compile(inputStream, builder.build()).render(data);
// 设置强制下载不打开
response.setContentType("application/force-download");
response.addHeader("Access-Control-Expose-Headers", " Content-Disposition");
if (fileType.equals(1)) {
//如果需要导出为word
response.addHeader("Content-Disposition", "attachment; fileName=" + new String(("导出模板.docx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
render.write(response.getOutputStream());
} else if (fileType.equals(2)) {
//如果需要导出为pdf
response.addHeader("Content-Disposition", "attachment; fileName=" + new String(("导出模板.pdf").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
//设置临时文件的地址
String tempPath = UUID.randomUUID() + ".docx";
//根据模板生成临时文件
render.writeToFile(tempPath);
//将docx流转换为pdf流
FileInputStream fileInputStream = new FileInputStream(tempPath);
WordConvertPdf.getPdfStreamByWordStream(fileInputStream, outputStream);
outputStream.flush();
outputStream.close();
fileInputStream.close();
//删除临时文件
File tempFile = new File(tempPath);
Files.delete(tempFile.toPath());
log.debug("删除临时word文件:{}", tempPath);
}
}
需要注意的时,文档中需要循环的数必须绑定biulder
![](https://file.jishuzhan.net/article/1711359276720590850/e5b807c20b8eb6e82e8984171342ecae.webp)
![](https://file.jishuzhan.net/article/1711359276720590850/12bd31a38f94dde81732e0662896e2a5.webp)
四、组装数据,createData方法
java
private ExportVO createData() {
ExportVO data = new ExportVO();
//普通文本
data.setTitle("食品统计");
data.setName("蔬菜统计");
data.setNum(60);
//集合数据
List<ExportListVO> list = new ArrayList<>();
list.add(new ExportListVO("黄瓜", 10));
list.add(new ExportListVO("茄子", 20));
list.add(new ExportListVO("番茄", 30));
//添加循环文本数据
data.setList(list);
//添加表格数据
data.setTable(list);
//添加柱状图数据
ChartMultiSeriesRenderData barChart = new ChartMultiSeriesRenderData();
barChart.setChartTitle("蔬菜统计柱状图");
barChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
List<SeriesRenderData> barChartSeriesData = new ArrayList<>();
barChartSeriesData.add(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
barChart.setSeriesDatas(barChartSeriesData);
data.setBarChart(barChart);
//添加饼图数据
ChartSingleSeriesRenderData pieChart = new ChartSingleSeriesRenderData();
pieChart.setChartTitle("蔬菜统计饼图");
pieChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
pieChart.setSeriesData(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
data.setPieChart(pieChart);
//添加折现图
ChartMultiSeriesRenderData lineChart = new ChartMultiSeriesRenderData();
lineChart.setChartTitle("蔬菜统计折线图");
lineChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
List<SeriesRenderData> lineChartSeriesData = new ArrayList<>();
lineChartSeriesData.add(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
lineChart.setSeriesDatas(lineChartSeriesData);
data.setLineChart(lineChart);
//添加图片
PictureRenderData img = new PictureRenderData(800, 200, "D:\\files\\img\\test.jpg");
data.setImg(img);
return data;
}
五、模板说明
1.这里面由{{}}包裹的内容对应ExportVO 实体中的属性名称
![](https://file.jishuzhan.net/article/1711359276720590850/e4619a324362e2c589a9ad640df194d6.webp)
2.这里的list对应ExportVO实体中的list属性,循环list写入文本,并判断是否是最后一条数据,最后一条数据由.句号结尾
![](https://file.jishuzhan.net/article/1711359276720590850/aa9b7b10788d0da5a0c7fcb9ee38f07b.webp)
3.table对应ExportVO实体中table属性,type和num对应集合实体类ExportListVO中的type和num
![](https://file.jishuzhan.net/article/1711359276720590850/3797e7447dc2953345a8196ab5b7f25c.webp)
4.模板中右键柱状图,查看可选文字,修改替换文字为ExportVO实体中柱状图属性名称{{barChart}}
![](https://file.jishuzhan.net/article/1711359276720590850/cea14b18f58a2ec0cc73eaffe699083f.webp)
5.模板中右键饼图,查看可选文字,修改替换文字为ExportVO实体中饼图属性名称{{pieChart}}
![](https://file.jishuzhan.net/article/1711359276720590850/5972882e5fac933743a496e64eab38e3.webp)
6.模板中右键折线图,查看可选文字,修改替换文字为ExportVO实体中折线图属性名称{{lineChart}}
![](https://file.jishuzhan.net/article/1711359276720590850/cd5d4f1f388882ff9236481cb22d270e.webp)
7.模板中右键图片,查看可选文字,修改替换文字为ExportVO实体中图片属性名称{{img}}
![](https://file.jishuzhan.net/article/1711359276720590850/c232e4b416751fd96f0d62a681b85117.webp)