poi-tl工具附上:
Poi-tl Documentation (deepoove.com)
引用:Maven
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.1</version>
</dependency>
正文:
在word模板中同时插入多张图片,我们使用的是区对块+图片标签的方式
{{?photo}}{{@img}}{{/photo}}
格式:
{
"photo": [
{ "img": "xxx.jpeg" },
{ "img": "aaa.jpeg" },
{ "img": "bbb.jpeg" }
]
}
实际代码:
public String exportDataWord(ExportWordDateDto dto, LoginVo loginVo) {
//1.1 查出模板 伪代码
Document formWordTemplate = xxxserviceImpl.getDataTempale();
//1.2 查出数据 键值对 伪代码
Document document = xxxserviceImpl.getData();
String url = null;
//2.读出模板,这里的模板是一个url,可以跟换成本地地址
if (ObjectUtil.isEmpty(formWordTemplate)) {
return "没有找到导出word数据模板!";
}
if (ObjectUtil.isEmpty(document)) {
return "当前表单没有数据,请先新增数据后在进行导出!";
}
//宽
Integer imagesWide = formWordTemplate.getInteger("images_wide");
//高
Integer imagesHigh = formWordTemplate.getInteger("images_high");
InputStream inputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
//请求模板文件
URL wordUrl = new URL(formWordTemplate.getString("word_url"));
HttpURLConnection conn = (HttpURLConnection) wordUrl.openConnection();
//设置超时间为3秒
conn.setConnectTimeout(3 * 1000);
//防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//得到输入流
inputStream = conn.getInputStream();
//图片字段 因为图片要做特殊处理,所以在设计模板的时候就把图片字段给提前拿出来了 这里就比如图片字段是 img
String[] imagesFields = formWordTemplate.getString("images_fields").split(",");
if (ObjectUtil.isNotEmpty(imagesFields)) {
List<String> imagesFieldList = Arrays.asList(imagesFields);
ArrayList<String> keyList = new ArrayList<>(document.keySet());
// 创建渲染数据
for (String key : keyList) {
//区块对list
List<Map<String, PictureRenderData>> list = new ArrayList<>();
if (imagesFieldList.contains(key)) {
Object o = document.get(key);
URL imageUrl = null;
//判断是否是list对象
if (o instanceof List) {
List<Document> documents = (List<Document>) o;
//这里采用得是poi-tl得区块对方式实现得
for (Document value : documents) {
//区块对list属性值
Map<String, PictureRenderData> map = new HashMap<>();
imageUrl = new URL(value.getString("url"));
HttpURLConnection urlConnection = (HttpURLConnection) imageUrl.openConnection();
if (200 == urlConnection.getResponseCode()) {
InputStream is = urlConnection.getInputStream();
//PictureType.suggestFileType(value.getString("url"))根据连接获取后缀名 一定要指定类型,不然图片数据展示出不来
map.put(key, Pictures.ofStream(is, PictureType.suggestFileType(value.getString("url"))).size(imagesWide, imagesHigh).create());
list.add(map);
}
}
} else {
imageUrl = new URL(document.getString(key));
HttpURLConnection urlConnection = (HttpURLConnection) imageUrl.openConnection();
if (200 == urlConnection.getResponseCode()) {
InputStream is = urlConnection.getInputStream();
document.put(key, Pictures.ofStream(is, PictureType.suggestFileType(document.getString(key))).size(imagesWide, imagesHigh).create());
}
}
//封装区对块得list外层对象 这里的phto就是word模板的图片的区对块标签
document.put("photo", list);
document.remove(key);
}
}
}
byteArrayInputStream = new ByteArrayInputStream(out.toByteArray());
XWPFTemplate template = XWPFTemplate.compile(inputStream).render(document);
template.write(outputStream);
//上传文件流伪代码
url = uploadFile(outputStream);
} catch (Exception e) {
e.printStackTrace();
return ResponseVo.fail2("服务异常,导出失败!");
} finally {
try {
if (ObjectUtil.isNotEmpty(inputStream)) {
inputStream.close(); // 关闭输入流
}
if (ObjectUtil.isNotEmpty(byteArrayInputStream)) {
byteArrayInputStream.close();
}
out.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//3.返回结果
return url;
}
运行结果:
模板:
实际内容:
上面代码涉及到一些伪代码,根据自己的业务进行相应的修改就可以了,返回值建议返回对象。