场景是查询数据然后导出excel,接口响应太慢。

处理接口慢,首先要找出哪个环节慢。

打日志看各环节花费时间,10W条数据 关联查询sql花费 3s,导出excel花费5S,响应传输时间很快不是关键问题。

网上导出excel框架有很多,easyExcel(阿里巴巴,占用内存小),easyPoi (API丰富),POI,jacob等。一样一样看。

1.EasyPoi

经查看,发现EasyPoi框架中的导出大文件API,其实是为了防止内存溢出,因为原本数据文件都被加载到内存中,并发导出大文件容易内存溢出,所以会将临时数据写入磁盘防止这个问题,而EasyExcel 天生就做到这一点。

但我们的目的是加快接口响应速度。

EasyExcel:https://alibaba-easyexcel.github.io/quickstart/fill.html#%E6%95%B0%E6%8D%AE%E9%87%8F%E5%A4%A7%E7%9A%84%E5%A4%8D%E6%9D%82%E5%A1%AB%E5%85%85

EasyPoi:https://opensource.afterturn.cn/doc/easypoi.html#8

2.EasyExcel

后来又查到一种,利用easyexcel分页sheet导出的方法,比如10W条数据,1W导出到一个sheet页,利用EasyExcel可以做到这一点。如:https://www.cnblogs.com/ningJJ/p/11435465.html

但这个方法经试验,其实每个sheet间依然是串行的,并不能加快接口速度。

我尝试用多线程并发导出各个sheet失败了,poi 对单个文件的多sheet写并不支持多线程,会重复写到同一sheet上,程序报错。

3.JACOB

还有JACOB, JAVA-COM Bridge的缩写,(提供自动化的访问com的功能,也是通过JNI功能访问windows平台下的com组件或者win32系统库的)。这是利用C完成对office的操作,之前用过它转码PPT为图片,很快,但只能运行在windows上,虽然快但是不满足需求。

4.HuTool

Hutool工具类中也有BigExcelWriter,用于大文件写出,但还是只解决内存溢出的问题。

ZIPUtil,压缩文件,我们的问题在写,不是在于数据传输,所以也没用。

5.CSV

最后发现,有一种最快的方式,就是将文件导出为CSV格式。

其实POI是针对每个单元格去写,包含样式字体宽度等等,不仅IO任务重,计算任务也重,如果是csv,直接是文本的写,其实就是直接用Printer流去写一行一行的字符,非常快,但缺点是不能在程序中进行单元格样式调整。

  • EasyPOI中有CSV的API,但我试验失败了,最后使用的 阿帕奇的Commoms-csv。
  • 而之前的关联5表查询sql,改成了多次进入数据库单表查询,时间由3s变为2s.
  • 另外,csv导出时,必须将编码设置为GBK,否则用excel打开时中文乱码,(但这样用其他软件打开时乱码,先不管了)。网上有一种将在文件最前面写入几个字节作bom,使excel软件识别文件的编码方式为utf—8,但我试验这种方式失败了。https://www.iteye.com/blog/rainbow702-1426354
 public void logDownload(@RequestBody LogExportParam param, HttpServletResponse response) throws IOException, InterruptedException {response.setContentType("application/csv");response.setCharacterEncoding("gbk");String fileName = "log" + System.currentTimeMillis() + ".csv";response.setHeader("Content-disposition", "attachment;filename=" + fileName);//设置编码格式,否则中文乱码String encoding = "GBK";Writer outputStreamWriter = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), encoding));CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader("序号", "日志类型", "描述", "校区", "教学楼", "教室", "操作时间", "操作人");CSVPrinter csvPrinter = new CSVPrinter(outputStreamWriter, csvFormat);logger.info("开始查询数据" + new Date().getMinutes() + "n" + new Date().getSeconds() + "s");List<ClassroomList> classroomList = classroomInfoService.classroomList(param.getSchoolId(), param.getTeachingBuildingId(), param.getClassroomId());if (CollectionUtils.isEmpty(classroomList))return;List<Long> classroomIds = classroomList.stream().map(ClassroomList::getClassroomId).collect(Collectors.toList());Map<Long, ClassroomList> classroomMap = classroomList.stream().collect(Collectors.toMap(ClassroomList::getClassroomId, Function.identity()));List<LogListDto> data = logService.logExportData(param, classroomIds);List<Long> userIds = data.stream().map(LogListDto::getCreateUserId).distinct().collect(Collectors.toList());Map<Long, String> usernameMap = authService.list(new QueryWrapper<IotSysUser>().select("username", "user_id").in("user_id", userIds)).stream().collect(Collectors.toMap(IotSysUser::getUserId, IotSysUser::getUsername));for (LogListDto log : data) {ClassroomList classroom = classroomMap.get(log.getClassroomId());log.setClassroomName(classroom.getClassroomName());log.setSchoolName(classroom.getSchoolName());log.setTeachingBuildingName(classroom.getTeachingBuildingName());log.setCreateUserName(usernameMap.get(log.getCreateUserId()));}logger.info("开始写文件" + new Date().getMinutes() + "n" + new Date().getSeconds() + "s");ListIterator<LogListDto> iterator = data.listIterator();while (iterator.hasNext()) {int index = iterator.nextIndex();LogListDto log = iterator.next();log.setSort(String.valueOf(index));csvPrinter.printRecord(log.getSort(), log.getLogType(), log.getRemark(), log.getSchoolName(), log.getTeachingBuildingName(), log.getClassroomName(), log.getCreateTime(), log.getCreateUserName());}logger.info("写出结束" + new Date().getMinutes() + "n" + new Date().getSeconds() + "s");data.clear();outputStreamWriter.flush();outputStreamWriter.close();}

java使用poi导出excel太慢相关推荐

  1. java利用poi导出excel功能-附带图片导出

    java利用poi导出excel功能-附带图片导出 写在前面 最近刚离职,闲来无事,于是把上两家公司都有碰到过的需求但都没有去研究实现:即导出带图片的excel报表.于是就折腾了一下这个功能,研究出来 ...

  2. java中poi导出Excel表格(前台流文件接收)

    java中poi导出Excel表格,前端以流的方式接收,而非直接生成文件再下载,解决多台服务器部署后,路径地址不统一导致的下载问题. 生成Excel示例图: 2.代码说明 ① 在上次的基础上增加了底部 ...

  3. Java操作poi导出Excel自定义字体颜色

    Java操作poi导出Excel自定义字体颜色 功能介绍 POI操作Excel 第一步创建一个导出的工具类 整体定义表格字体样式 自定义表格字体样式 总结 功能介绍 Apache POI 是用Java ...

  4. Java和poi导出excel报表

    一:poi jar下载地址:点击打开链接: 二:工程截图: 三:运行效果截图: 四:源代码: Student.java: package com.poi.bean;import java.util.D ...

  5. Java使用POi导出Excel(包含图片)

    Java使用poi组件导出excel报表,能导出excel报表的还可以使用jxl组件,但jxl想对于poi功能有限,jxl应该不能载excel插入浮动层图片,poi能很好的实现输出excel各种功能, ...

  6. java 使用poi导出excel,可控制固定前2列固定标头排版,带统计数据格式的

    使用poi导出排版漂亮的excel文件 html代码: <button class="btn btn-link" ng-model="exportExcel&quo ...

  7. poi导出excel 损坏_急!!!java用poi导出excel文件,打开导出的文件时报错“文件错误,数据可能丢失”...

    展开全部 两个原因: 1.你的excel模版本身有问题,可以尝试新建一个模版. 2.你的excel使用了一e68a8462616964757a686964616f31333365643662些POI不 ...

  8. java通过poi导出excel和pdf

    [背景] 由于各户的需求,所以需要增加导出excel这个功能,其实大部分系统都需要这个导出功能的,所以这里也就不详细说明具体导出的背景了O(∩_∩)O~ 干完导出excel将现有的导出pdf也进行了独 ...

  9. java使用poi导出Excel表发回浏览器或是保存到本地

    在实际工作中不可避免的会遇上统计.导出报表的工作,我自己整理了一份导出Excel代码放到这里,即为了分享知识,也是对自己的总结 首先导入依赖 <dependency><groupId ...

最新文章

  1. 数学——函数极限知识以及sympy库的limit
  2. android启动第三方应用
  3. python lambda_Python 匿名函数 lambda
  4. php通过QQ号获取QQ信息,通过openId能获取到QQ号码吗?
  5. 云原生生态周报 Vol. 12 | K8s 1.16 API 重大变更
  6. ScrollView常用(暂时用上了的)代理方法
  7. DBA_OBJECTS
  8. 学生用计算机如何解方程,学生党必备神器!一键解方程计算器App
  9. 极域电子教室功能讲解-电子教室
  10. snb处理器hd3000显卡专用extra_Intel十代酷睿处理器:移动平台性能有了质飞跃!...
  11. oracle汉字转换成拼音首字母和五笔首字母
  12. 三级模式两级映像/数据库系统结构
  13. 【java基础】三目表达式
  14. 关于高校通过ipv6免收费上网
  15. 第1天学习打卡(Javaweb 邮件发送:原理、发送简单文本邮件、发送带图片和附件邮件、网站注册发送邮件Servlet实现)
  16. Apache ab 测试使用指南
  17. 互联网理财产品上周收益播报排行榜
  18. win10 c 语言 全屏,win10所有的视频都不能全屏了,重装了好几次都是这样 ,求助 - Microsoft Community...
  19. 二维等离子体输运与反应动力学求解器PASSKEy中的数值和物理参数说明(附视频链接)
  20. 星环研发总监为你揭秘TDH8.0的前因后果 | TDH8.0 使用必读 3

热门文章

  1. 医护网电子商务商城网站策划方案
  2. 【Computer Graphics】直线方程及相关计算
  3. linux内核通用显卡驱动,一种通用的显卡驱动方法
  4. ARP***原理及解决方法(NBTSCAN扫描工具下载和nbtscan使用方法)
  5. C语言编译器概要设计思路一
  6. 【半年总结】思想与技术的腾飞
  7. c 语言中双向链表逆转编程题,C/C++ 双链表之逆序的实例详解
  8. 美刊评出2009年度十大发明
  9. DNF史诗计算机最新版,DNF韩械史诗计算器 V3.70 最新免费版
  10. sonic orch调度系统(1)----select