100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > POI-tl导出Word文档表格并且带图片+浏览器导出

POI-tl导出Word文档表格并且带图片+浏览器导出

时间:2018-12-23 12:07:25

相关推荐

POI-tl导出Word文档表格并且带图片+浏览器导出

POI-tl导出Word文档表格并且带图片+浏览器导出

说在前面的话

这两天有个以前的没碰过的项目提出来一个需求,导出word表格,并且是循环表格,注意是循环表格,而不是循环数据,当然既然是循环表格,顺带的数据肯定也要循环,还要带图片。先看看需求图(这是我自己参照需求画的,格式和需求一样)

模版

正文

我们用poi-tl:poi-tl是一个基于Apache POI的Word模板引擎,同时它也是一个免费开源(github地址)的Java类库,给Java程序员带来了word处理上的便捷。所需环境:

1. pom.xml 文件

<!--word导出相关依赖--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>

2. pom.xml配置java代码获取resource下面word模版文件(很多博客都没看到这个配置)

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><configuration><encoding>UTF-8</encoding><!-- 过滤后缀文件 --><nonFilteredFileExtensions><!--<nonFilteredFileExtension>xlsx</nonFilteredFileExtension><nonFilteredFileExtension>xls</nonFilteredFileExtension>--><nonFilteredFileExtension>docx</nonFilteredFileExtension></nonFilteredFileExtensions></configuration></plugin>

3.java 代码测试类(当前测试类,可以复制到本地直接运行,前提是上面的pom.xml已经配置好,哦,还有图片地址换成自己本地的)

import com.deepoove.poi.XWPFTemplate;import com.deepoove.poi.data.*;import mon.util.DateUtils;import org.jeecg.modules.jointLogisticSupport.controller.JointLogisticSupportController;import org.jeecg.modules.jointLogisticSupport.entity.JointLogisticSupport;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import .HttpURLConnection;import .URL;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class ExportTest {/*** 导出文件具体业务* @throws Exception*/public static void main(String[] args) throws Exception {// 模版放在resourceString filePath = "/jointTemplate.docx";// 获取模版文件流InputStream inputStream = JointLogisticSupportController.class.getResourceAsStream(filePath);if (inputStream == null) {throw new IllegalArgumentException("Template file not found: " + filePath);}// 表格头RowRenderData tableHead = Rows.of("编号", "规格", "位置","状态").center().bgColor("4472c4").create();// 数据列表List<JointLogisticSupport> pageList = new ArrayList<>(5);// 创建表格listList<RowRenderData> rowDataList = new ArrayList<>();List<RowRenderData> rowDataList1 = new ArrayList<>();Map<String,Object> map = new HashMap<>();// 循环创建每一行表格int order = 1;for (int i = 0; i < 5; i++) { // 这里我就直接循环了,查出来的list数据自行循环rowDataList.add(Rows.create(order+"", "规格"+order, "位置"+order,"正常"));order ++;// 第二个表格rowDataList1.add(Rows.create("产品名称","产品"+order,"描述","描述","状态","正常"));rowDataList1.add(Rows.create("检验是否合格","是","检验日期","yyyy-mm-dd","检验人","程序猿"));// 图片路径String east = null;String prospectMap = null;// 因为创建表格时不能放入图片,所以先生成一个图片占位符放在临时文件中String eastPicture = null;String prospectMapPicture = null;// 把word中的占位符对应的值存入mapString eastPic = null;String prospectMapPic = null;// 把占位符和图片路径放在map中/*** 下面注释部分是自己项目的代码,现在把它注释掉* 我们写测试用的代码*///if (StringUtils.isNotEmpty(item.getEast())){//east =item.getEast();//if(loadUrl(east)){// eastPicture = "{{@eastPicture"+order+"}}";// eastPic = "eastPicture"+order;// map.put(eastPic, Pictures.ofUrl(east).size(86, 86).create());//}//}//if (StringUtils.isNotEmpty(item.getProspectMap())){//prospectMap =item.getProspectMap();//if(loadUrl(prospectMap)){// prospectMapPicture = "{{@prospectMapPicture"+order+"}}";// prospectMapPic = "prospectMapPicture"+order;// map.put(prospectMapPic,Pictures.ofLocal(prospectMap).size(86, 86).create());//}//}// word 文档占位符eastPicture = "{{@eastPicture"+order+"}}";prospectMapPicture = "{{@prospectMapPicture"+order+"}}";// java 代码对应占位符的key键eastPic = "eastPicture"+order;prospectMapPic = "prospectMapPicture"+order;// 图片map数据map.put(eastPic,Pictures.ofLocal("E:\\正面.jpg").size(86, 86).create());map.put(prospectMapPic,Pictures.ofLocal("E:\\收割机侧面.jpg").size(86, 86).create());rowDataList1.add(Rows.create("正面照",eastPicture,null,"侧面照",prospectMapPicture,null));}// 合并规则,创建两个,第一个表格规则MergeCellRule rule = MergeCellRule.builder().build();// 第二个表格规则MergeCellRule.MergeCellRuleBuilder mergeRuleBuilder = MergeCellRule.builder();// 根据特定条件设置合并规则for (int i = 0; i < rowDataList1.size(); i++) {// 在此处根据具体条件来判断是否要设置合并规则if (i%3==2){mergeRuleBuilder.map(MergeCellRule.Grid.of(i, 1), MergeCellRule.Grid.of(i, 2)).map(MergeCellRule.Grid.of(i, 4), MergeCellRule.Grid.of(i, 5));}}MergeCellRule rule1 = mergeRuleBuilder.build();// 第一次生成的临时文件String prefix = String.valueOf(System.currentTimeMillis());File tempFile = File.createTempFile(prefix, ".docx");// 获取临时文件路径String firstTargetPath = tempFile.getAbsolutePath();// 根据模版填充临时文件XWPFTemplate template = pile(inputStream).render(new HashMap<String, Object>() {{// 生成第一个表格TableRenderData table = Tables.of(tableHead).center().create();// 逐行添加数据到表格for (RowRenderData rowData : rowDataList) {table.addRow(rowData);}// 设置合并规则table.setMergeRule(rule);put("table", table);// 生成第二个表格TableRenderData table1 = Tables.create();// 逐行添加数据到表格for (RowRenderData rowData : rowDataList1) {table1.addRow(rowData);}// 设置合并规则table1.setMergeRule(rule1);put("table1", table1);}});template.writeAndClose(new FileOutputStream(firstTargetPath));// 获取临时文件模版,并把图片存入表格中XWPFTemplate templatePic = pile(firstTargetPath).render(map);Long currentTime = DateUtils.getCurrentTimestamp();String fileName = "信息采集_"+currentTime+".docx";String path = "E:\\" + fileName;// 写入templatePic.writeAndClose(new FileOutputStream(path));// 删除创建的临时文件deleteFile(firstTargetPath);//response.getOutputStream().write(fileName.getBytes());}/*** 删除临时文件* @param filePath*/private static void deleteFile(String filePath) {File file = new File(filePath);if (file.exists()) {file.delete();}}/*** 访问图片是否存在* @param imageUrl* @return*/private boolean loadUrl(String imageUrl){try {// 创建URL对象URL url = new URL(imageUrl);// 打开连接HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("HEAD");// 获取响应状态码int responseCode = connection.getResponseCode();connection.disconnect();if (responseCode == HttpURLConnection.HTTP_OK) {System.out.println("图片存在");// 关闭连接return true;} else {// 关闭连接System.out.println("图片不存在");return false;}} catch (IOException e) {System.out.println("发生异常:" + e.getMessage());return false;}}}

执行效果

执行完之后会在电脑上生成一个word文档。

前端导出word文档

1.需要把main方法的最后一句打开

2. 前端vue代码,自动下载的

// 导出按钮点击事件方法handleExportWord() {let param = this.getQueryParams();if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {param['selections'] = this.selectedRowKeys.join(",");}console.log("导出参数", param);// 改成自己项目封装好的get方法,请求方法改成自己的getAction(this.url.exportWordUrl,{param:param,// responseType:'blob'}).then(response => {console.log('test',response);if (!response) {return}const url = window._CONFIG['staticDomainURL']+'//'+response;const link = document.createElement('a');link.style.display = 'none';link.href = url;link.setAttribute('download', fileName + '.docx');document.body.appendChild(link);link.click();document.body.removeChild(link);window.URL.revokeObjectURL(url);}).catch(error => {console.error(error);this.$message.warning("文件下载失败");});}

最后

这个放入图片的方法是一种比较笨的方法,但是能达到实现效果,我也查了很多博客,文档,但是没有看到循环表格时加入图片的,其他人如果有好的方法发出来,大家一起学习。

参考文档:

参考博客

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。