Apache组件POI,将图片下载到Excel文件中并导出。

      在日常的工作中,有时我们会遇到需要将数据库表中图片字段下载到Excel中的需求,为方便各位小伙伴今后的开发工作,我将分享出自己写的代码,并指出图片下载到Excel文件中的性能瓶颈问题。 在文章末尾有我上传到 Gitee 上的 Demo案例,希望大家喜欢。

      将图片下载到Excel文件中并导出,先看一下效果。

1、使用的 POI 依赖

     需要说明的是: commons-io 依赖必须有,不然在编写代码的过程中会异常。由于 POI 组件版本升级的问题,本文分享的代码适合 3.17 版本的依赖,版本太高的jar包可能不适合。

     在我自己学习、测试过程中,5.2.0版本的POI组件Jar包就不适合本文的代码。 

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version><!--<version>5.2.0</version>-->
</dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version><!--<version>5.2.0</version>-->
</dependency>

2、关键部分代码展示

      在以下的函数中,大体分为以下几步:

      2-1、查询获取结果值:userVOList ,并将其转成导出 exportVOS ;

      2-2、创建工作簿对象workbook,并因此创建工作表对象 sheet ;

      2-3、对工作表 sheet工作表对象 设置头部标题数据、头部标题样式;

      2-4、对 sheet工作表对象 填充数据,这些数据分为普通文本数据、图片数据。

      2-5、将工作簿对象 workbook 输出。  


/**** 用户信息 导出** @param paramDTO  用户入参DTO* @param response  response请求** @return* @author moon  2023/6/27 10:31*/@Overridepublic void exportUser(UserParamDTO paramDTO, HttpServletResponse response) throws Exception {// 1-1、获取列表查询数据List<UserVO> userVOList = userMapperExt.selectUserByParamDTO(paramDTO);// 1-2、将 UserVO 转成 UserExportVOList<UserExportVO> exportVOS = userVOList.stream().map(infoVO -> BeanUtils.convert(infoVO, UserExportVO.class)).collect(Collectors.toList());//空数据导出不了标题 需要放一个空对象if (CollectionUtils.isEmpty(exportVOS)) {exportVOS = new ArrayList<>();}// Map<'英文名', '中文名'> 组合形式.Map<String, String> aliasMap = ExcelUtils.getDTOAliasTitle(UserExportVO.class, Constant.BooleanFlag.FALSE);List<String> headerList = new ArrayList<>(aliasMap.keySet());// 2-1、创建 工作簿 对象.Workbook workbook = new XSSFWorkbook();// 2-2、创建工作表对象Sheet sheet = workbook.createSheet();// 设置标题行,第0行.Row headerRow = sheet.createRow(Constant.Digital.ZERO);// 获取头部单元格样式CellStyle headerCellStyle = ExcelUtils.getCellStyle(workbook, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, Constant.Digital.ONE);// 2-3、设置头部单元格样式for (int i = 0; i < headerList.size(); i++) {// 获取中文值String value = aliasMap.get(headerList.get(i));Cell cell = headerRow.createCell(i);// 设置 样式cell.setCellStyle(headerCellStyle);// 设置 值cell.setCellValue(value);}// 2-4、填充单元格数据for (int i = 0; i < exportVOS.size(); i++) {// 创建行对象,从第1行开始。int rowNum = i + 1;Row row = sheet.createRow(rowNum);UserExportVO tempVO = exportVOS.get(i);// 创建单元格对象(列)并设置值for (int j = 0; j < headerList.size(); j++) {Cell cell = row.createCell(j);Field field = UserExportVO.class.getDeclaredField(headerList.get(j));// 若属性为私有,需要设置可访问。field.setAccessible(Constant.BooleanFlag.TRUE);String fieldName = field.getName();String fieldValue;if (Objects.isNull(field.get(tempVO))) {fieldValue = Constant.CommonlySymbols.EMPTY;} else {fieldValue = field.get(tempVO).toString();}if (StringUtils.equalsAny(fieldName, UserVO.FIELD_HEAD_PHOTO, UserVO.FIELD_SCHOOL_PHOTO)&& StringUtils.isNotBlank(fieldValue)) {  // 2个图片字段,需要特殊处理.// 构造 URLString path = field.get(tempVO).toString();URL url = new URL(path);// 打开连接URLConnection con = url.openConnection();//设置请求超时为5scon.setConnectTimeout(8 * 1000);// 输入流InputStream is = con.getInputStream();byte[] bytes = IOUtils.toByteArray(is);@SuppressWarnings("static-access")int pictureIdx = workbook.addPicture(bytes, workbook.PICTURE_TYPE_PNG);  // 添加图片到工作簿中CreationHelper helper = workbook.getCreationHelper();  // 获取创建帮助类Drawing drawing = sheet.createDrawingPatriarch();   // 获取绘图父对象ClientAnchor anchor = helper.createClientAnchor();  // 创建客户端锚点// 图片插入坐标anchor.setCol1(j);  // 设置图片左上角的列数anchor.setRow1(rowNum);  // 设置图片左上角的行数// 插入图片Picture pict = drawing.createPicture(anchor, pictureIdx);  // 在指定位置插入图片// 设置 单元格高度cell.getRow().setHeight((short) 1000);  // 将单元格所在行的高度设置为1000// 设置 单元格宽度sheet.setColumnWidth(cell.getColumnIndex(), 2600);  // 将单元格所在列的宽度设置为2600// 设置图片宽、高放缩比例pict.resize(1, 1);  // 这行代码,可以将值设置成 pict.resize(0.5, 0.5)、pict.resize(2, 2),看看效果如何。} else {cell.setCellValue(fieldValue);}}}// 将工作簿写入文件中try {response = ExcelUtils.getHttpServletResponse(response, Constant.ExcelProperty.USER_EXPORT_NAME);ServletOutputStream outputStream = response.getOutputStream();workbook.write(outputStream);} finally {workbook.close();}}

       由于数据库表中存在的是图片的URL地址,在获取图片信息时,需要逐个调用URL获取数据,当图片数据量较大时,会出现超时问题、网络IO问题,这也是图片下载的瓶颈所在。   

3、使用Postman进行测试

3-1、测试的URL:http://localhost:8080/user/exportUser

3-2、入参参数:

{"age": "","createDate": "","distinct": true,"id": "","isDeleted": "","name": ""
}

3-3、返回结果:

    在之后的时间里,我将还会分享 Excel勾选导出 代码案例,希望能够帮到大家。

Gitee上的Demo案例:  apache-poi-demo   ,项目名称:apache-poi-demo .             

入口函数:com.moon.poi.service.impl.UserServiceImpl#exportUser(...)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/7875.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis高可用——哨兵模式

Redis——哨兵模式 一、Redis 哨兵模式1.哨兵模式的作用2.故障转移机制3.主节点的选举 二、搭建Redis 哨兵模式1.修改 Redis 哨兵模式的配置文件&#xff08;所有节点操作&#xff09;2.启动哨兵模式3.查看哨兵信息4.故障模拟5.验证结果 一、Redis 哨兵模式 主从切换技术的方法…

少数人的晚餐

这不是影评。 这是过去现在和未来都必然发生的事情。 如下这句话选自这部电影&#xff1a; P-Power M-Money K-knowledge 但本文与电影无关。 有一句大家经常听到的话&#xff1a; “群众的眼睛是雪亮的” 但事实上更普遍存在的是&#xff1a; P一定掌握在少数人手中&…

数据库性能测试报告总结模板

目录 1计划概述 2参考资料 3术语解释 4系统简介 5测试环境 6测试指标 7测试工具和测试策略 8测试数据收集 9测试结果数据以及截图 9.1Jmeter性能指标 9.2硬件指标图 10 测试结论 需要完整报告模板记得文章末尾找我哦。 1计划概述 目的&#xff1a;找出系统潜在的…

Elasticsearch集群

单点的问题 单台机器存储容量有限&#xff0c;无法实现高存储。 单服务器容易出现单点故障&#xff0c;无法实现高可用。 单服务的并发处理能⼒有限&#xff0c;无法实现高并发。 集群的结构 数据分片:把数据拆分成多份&#xff0c;每一份存储到不同机器节点&a…

[Flask] Cookie与Session

由于HTTP的无状态性&#xff0c;为了使某个域名下的所有网页能够共享某些数据&#xff0c;Cookie和Session应运而生 1.Cookie对象 HTTP是无状态(stateless)协议&#xff0c;一次请求响应结束后&#xff0c;服务器不会留下任何关于对方状态的信息 也就是说&#xff0c;尽管在…

制造企业实施MES系统受到的影响因素有哪些?

实施MES系统会遇到哪些影响因素&#xff1f;或者说企业实施MES系统的交付率为什么低&#xff1f; 我觉得关键点在于&#xff1a;在当前MES产品化程度普遍不高的大环境下&#xff0c;对项目及管理软件本身认知过于简单&#xff0c;且缺失有经验行业人才&#xff0c;是当前大部分…

GitHub打不开的解决方案(超简单)

在国内&#xff0c;github官网经常面临打不开或访问极慢的问题&#xff0c;不挂梯子&#xff08;VPN&#xff0c;飞机&#xff0c;魔法&#xff09;使用体验极差&#xff0c;那有什么好办法解决GitHub官网访问不了的问题&#xff1f;今天小布教你几招轻松访问github官网。 git…

【运维】Windows 通过注册表禁用服务

【运维】Windows 通过注册表禁用服务 以这个服务为例子 Windows Push Notifications User Service 双击查看服务名称 WpnUserService_671f3 打开注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{服务名称} HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Ser…

wireshark学习

抓包原理 哪种网络情况可以抓到包&#xff1f;&#xff08;1&#xff09;本机环境&#xff08;2&#xff09;集线器环境&#xff08;3&#xff09;交换机环境 交换机环境目前较为常用&#xff0c;这也分为三种情况&#xff08;1&#xff09;端口镜像&#xff08;2&#xff09…

Jenkins构建Python项目提示:‘python‘ 不是内部或外部命令,也不是可运行的程序

一、问题描述&#xff08;1&#xff09; 今天Darren洋在jenkins里构建与飞书机器人通知时&#xff0c;用python编写脚本时发现了以下报错&#xff1a;Jenkins构建Python项目提示&#xff1a;‘python‘ 不是内部或外部命令&#xff0c;也不是可运行的程序 二、解决办法 在配置…

vue+leaflet笔记之热力图

vueleaflet笔记之热力图 文章目录 vueleaflet笔记之热力图开发环境代码简介插件简介与安装使用简介 详细源码(Vue3) 本文介绍了Web端使用 Leaflet开发库展示热力图方法 (底图来源:天地图)&#xff0c;结合leaflet.heat插件可以很容易的做出热力图&#xff0c;通过调整其配置参…

记一次使用MySQL数据库ORM为 SqlSugar 事务无效的处理过程

在项目中使用了开源代码框架admin.net &#xff0c;其使用的数据库ORM为SqlSugar 使用以下代码执行事务理论上应该有回滚发生&#xff0c;但数据任然删除了 [UnitOfWork][ApiDescriptionSettings(Name "Delete")] [HttpPost][DisplayName("删除菜单")]p…