一、写在前面
最近在项目中使用到了poi-tl导出word文档,该文档包含内容比较丰富,包含动态表格、动态行、图片、多个图片以及使用等比例缩放。该版本只支持word模板是.docx的文件。
二、准备工作
1、引入依赖
避免与已导入的commons-io版本冲突,建议将依赖的排除,这一步很重要。
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.8.0</version>
<exclusions>
<!-- 排除 commons-io 2.5 -->
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
</exclusions>
</dependency>
三、各种导出示例
1、基本信息
语法格式
// 具体的字段名
{{projectName}}
模板设置
代码示例
// 获取模板
XWPFDocument doc = null;
ServletOutputStream outputStream = null;
try {
// 获取文件路径
String path = WordExportUtil.templatePath("labTestReportNew.docx");
log.info("path:{}", path);
doc = new XWPFDocument(POICacheManager.getFile(path));
Map<String,Object> dataMap = new HashMap<>();
// 构造导出的map数据
// 封面-多选的样件名称多个使用顿号各开
dataMap.put("sampleNameSummary", String.join("、", sampleNameList));
// 封面-样件对应的型号多个使用顿号各开
dataMap.put("sampleCodeSummary", String.join("、", sampleCodeList));
XWPFTemplate template = XWPFTemplate.compile(templateStream, configure).render(dataMap);
// 删除空白页
List<IBodyElement> bodyElements = template.getXWPFDocument().getBodyElements();
template.getXWPFDocument().removeBodyElement(bodyElements.size() - 1);
template.getXWPFDocument().removeBodyElement(bodyElements.size() - 2);
outputStream = response.getOutputStream();
response.addHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(reportDetailDTO.getBaseDTO().getCode(), "utf-8"));
template.write(outputStream);
template.close();
} catch (Exception e) {
e.printStackTrace();
log.error("error:{}", e);
} finally {
WordExportUtil.close(doc, outputStream);
}
结果展示
2、图片信息
语法格式
// 判断是否为空,不为空输出
{{?ratifyImg}}{{@#this}}{{/ratifyImg}}
模板设置
代码示例
这里演示得是本地图片如何导出,多图片导出时会演示网络图片及文件服务器问题如何导出
// 高,宽,图片类型这个.一定要加,找到图片位置将他读取
PictureRenderData ratifyImg= new PictureRenderData(90, 40, ".jpg", this.getClass().getClassLoader().getResourceAsStream("signaturePic/"+ratifyUser+".jpg"));
// 批准人签名
dataMap.put("ratifyImg", ratifyImg);
PictureRenderData toExamineImg= new PictureRenderData(90, 40, ".jpg", this.getClass().getClassLoader().getResourceAsStream("signaturePic/"+toExamineUser+".jpg"));
// 审核人签名
dataMap.put("toExamineImg", getSignaturePic("ratify", toExamineImg);
结果展示
3、动态表格的行列
语法格式
// 判断是否为空,不为空输出
{{?definitionTestItemList}}
// 循环取出该对象中的值
{{testItem}}
{{/definitionTestItemList}}
模板设置
代码示例
List<JSONObject> definitionTestItemList = Lists.newArrayList();
for (LabTestReportDefinitionDTO labTestReportDefinitionDTO : definitionList) {
JSONObject definitionJson = BeanUtil.copyProperties(labTestReportDefinitionDTO, JSONObject.class);
// 处理富文本数据
String testResultAttachment = labTestReportDefinitionDTO.getTestResultAttachment();
List<JSONObject> testResultList = getPicList(testResultAttachment, 0, 220);
definitionJson.put("testResult", Optional.ofNullable(testResultList).orElse(new ArrayList<>()));
// 处理判断依据图片
String assessAttachment = labTestReportDefinitionDTO.getAssessAttachment();
definitionJson.put("assessAttachmentPicList", getPicList(assessAttachment, 0,220));
// 处理测试标准图片
String standardAttachment = labTestReportDefinitionDTO.getStandardAttachment();
definitionJson.put("standardAttachmentPicList", getPicList(standardAttachment, 0,220));
// 处理试验偏离图片
String testDeviationAttachment = labTestReportDefinitionDTO.getTestDeviationAttachment();
definitionJson.put("testDeviationAttachmentPicList", getPicList(testDeviationAttachment, 0,220));
definitionTestItemList.add(definitionJson);
}
dataMap.put("definitionTestItemList", Optional.ofNullable(definitionTestItemList).orElse(new ArrayList<>()));
效果展示
4、动态循环表格的行信息
语法格式
// 判断是否为空,不为空输出
{{?equipmentJsonList}}
// 该对象中每个对象的取值,与上述表格行列的循环稍微有点区别 [属性名]
[equipmentName]
模板设置
代码示例
// com.deepoove.poi.policy.HackLoopTableRenderPolicy
Configure configure = Configure.newBuilder().build();
// 这里需要声明一下,是动态行循环策略,不然导出会有问题
configure.customPolicy("equipmentJsonList", new HackLoopTableRenderPolicy());
dataMap.put("equipmentJsonList", Optional.ofNullable(equipmentJsonList).orElse(new ArrayList<>()));
效果展示
5、多图片导出-非本地图片
语法格式
// 图片列表
{{?picList}}
// 该对象中存储图片的对象属性是fileImg
{{@fileImg}}
{{/picList}}
模板设置
代码示例
List<JSONObject> picList = getPicList(labTestReportSampleDTO.getTestCurve(), 0,700);
sampleTestCurvePicList.addAll(picList);
List<String> fileIdList = Lists.newArrayList();
for (String fileId: fileIdList) {
JSONObject picJson = new JSONObject();
picJson.put("fileName", "测试图片");
// 先根据文件id将文件下载出来,一般下载后是个字节数组
BufferedImage image = ImageIO.read(new ByteArrayInputStream(body));
// 读取图片原始高宽,测试过导出可能会失真,所以这边先暂时等比例都除以2 大家可以按照自身图片进行处理
int originalWidth = image.getWidth() /2;
int originalHeight = image.getHeight() /2;
PictureRenderData pictureRenderData = new PictureRenderData(originalWidth,originalHeight, ".jpg", body)
picJson.put("fileImg", pictureRenderData);
attachmentPicList.add(picJson);
}
// 图片数组
dataMap.put("sampleTestCurvePicList", Optional.ofNullable(picList ).orElse(new ArrayList<>()));
效果展示
四、官方参考文档
https://deepoove.com/poi-tl/1.6.x/#_requirements