POI使用--循环word模版填入对应数据图片(包含嵌套循环)
Posted lllllLiangjia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POI使用--循环word模版填入对应数据图片(包含嵌套循环)相关的知识,希望对你有一定的参考价值。
1.目录结构
2.引入依赖
<!--poi-tl word支持-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.2</version>
</dependency>
3.准备word模版数据
健康宝-同时空协查函模板.docx 内容如下
?section1
北京市疾病预防控制中心关于
新型冠状病毒感染病例
接触者的协查函
健康宝注册人员:姓名:healthKitGeneratorName ,电话:phone ,身份证号:icNumber ,二维码见附图,谢谢!
望尽早协助为盼。
疾病预防控制中心
附图:健康宝扫码登记二维码
?qrCode
@pictures
/qrCode
/section1
注意点1:如果是普通文字输出在word模版上,则要用变量名替代。如果是图片的话。要用@变量名替代。
注意点2:遍历模版输出使用的是 区块对 标签,该标签使用格式
?变量名
模版和数据
/变量名
区块对标签官网地址:Poi-tl Documentation
注意点3:由于项目需求,单独一个协查函可能包含多个二维码图片信息。所以我使用了循环嵌套区块对标签,最外层section1标签是循环输出模版整个协查函模版,与HealthKitLetterInfo类对象对应。内层的qrCode标签是循环输出图片,与HealthKitLetterInfo类内的qrCode属性对应。
4.实体创建
4.1 PointPositionForm类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PointPositionForm
private List<String> healthKitScreenshots;
private String healthKitGeneratorName;
private String phoneNum;
private String idNum;
4.2 HealthKitLetterInfo类
由于在paramMap中区块对的标签变量对应的是该类的集合。该实体内的字段属性要与word模版中变量名对应
@Data
@Builder
public class HealthKitLetterInfo
private String healthKitGeneratorName;
private String phone;
private String icNumber;
private List<Map<String, PictureRenderData>> qrCode;
5.word文档输出逻辑
public static void main(String[] args)
Map<String, Object> paramMap = new HashMap<>();
// 创建两个有数据的实体
List<PointPositionForm> healthKits = new ArrayList<>();
healthKits.add(PointPositionForm.builder()
.phoneNum("1333333333")
.idNum("我是身份证号1")
.healthKitGeneratorName("测试姓名1")
.healthKitScreenshots(Arrays.asList(
"/Users/liangjiabao/Downloads/Snipaste_2022-05-18_14-25-25.png",
"/Users/liangjiabao/Downloads/测试图.png",
"/Users/liangjiabao/Downloads/Snipaste_2022-05-18_14-25-25.png"
)).build());
healthKits.add(PointPositionForm.builder()
.phoneNum("18888888888")
.idNum("我是身份证号2")
.healthKitGeneratorName("测试姓名2")
.healthKitScreenshots(Arrays.asList(
"/Users/liangjiabao/Downloads/测试图.png",
"/Users/liangjiabao/Downloads/Snipaste_2022-05-18_14-25-25.png"
)).build());
List<HealthKitLetterInfo> healthKitLetterInfos = new ArrayList<>();
// 遍历两个实体,将数据添加到word文档模版对应的实体上
for (PointPositionForm healthKit : healthKits)
HealthKitLetterInfo healthKitLetterInfo = HealthKitLetterInfo.builder()
.healthKitGeneratorName(healthKit.getHealthKitGeneratorName())
.phone(healthKit.getPhoneNum())
.icNumber(healthKit.getIdNum())
.qrCode(new ArrayList<>())
.build();
// 多个健康宝二维码
List<String> healthKitScreenshots = healthKit.getHealthKitScreenshots();
List<Map<String, PictureRenderData>> qrCode = healthKitLetterInfo.getQrCode();
for(String imageUrl : healthKitScreenshots)
Map<String,PictureRenderData> map=new HashMap<>();
map.put("pictures", new PictureRenderData(100, 120, imageUrl));
qrCode.add(map);
healthKitLetterInfos.add(healthKitLetterInfo);
paramMap.put("section1",healthKitLetterInfos);
// 生成文件
Map<String, String> resultMap = createPdf(paramMap);
private static Map<String, String> createPdf(Map<String, Object> paramMap)
log.info("生成电子协查函参数paramMap = ", paramMap);
// 文件存放根目录
String rootPath = "/Users/liangjiabao" + File.separator ;
File dir = new File(rootPath);
// 文件夹不存在则创建
if (!dir.exists())
boolean mkdir = dir.mkdir();
if (!mkdir)
log.error("文件目录创建失败");
String docxPath = rootPath + "健康宝-同时空协查函" + ".docx";
String imgPath = rootPath + "image" + File.separator;
// 获取电子协查函模板
String path = "file-template" + File.separator + "健康宝-同时空协查函模板.docx";
// 根据模板渲染word、并且生成pdf文件
ClassPathResource classPathResource = new ClassPathResource(path);
try (InputStream inputStream = classPathResource.getInputStream())
if (Objects.isNull(inputStream))
log.error("获取电子协查函模板失败");
// 通过协查函模板,开始生成电子协查函
try (XWPFTemplate template = XWPFTemplate.compile(inputStream).render(paramMap);
OutputStream outDocx = Files.newOutputStream(Paths.get(docxPath)))
NiceXWPFDocument xwpfDocument = template.getXWPFDocument();
// 输出word
template.getXWPFDocument().write(outDocx);
catch (Exception e)
log.error("创建协查函异常,异常详情:\\n", e);
Map<String, String> map = new HashMap<>(4);
map.put("rootPath", rootPath);
map.put("docxPath", docxPath);
return map;
输出文件结果
以上是关于POI使用--循环word模版填入对应数据图片(包含嵌套循环)的主要内容,如果未能解决你的问题,请参考以下文章
POI使用--循环word模版填入对应数据图片(包含嵌套循环)
POI根据模板导出word文件,以及word转PDF,PDF转图片再插入PDF中(防止PDF被修改)