项目场景:

导出40万以上的数据到xlsx


问题描述:

实施地出现导出40万数据到excel中时,CPU占不超过100%,时间超过半个小时,系统中其他功能模块卡顿

 @EcpGetMapping("/exportResultDetail")public void exportResultDetail(final HttpServletRequest req, final HttpServletResponse resp, @RequestParam final String operParams) {byte[] exportBytes = null;ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();try {JSONObject jsonObj = JSONObject.parseObject(operParams);String fileName = String.valueOf(jsonObj.get("fileName"));String fileType = String.valueOf(jsonObj.get("fileType"));String compId = String.valueOf(jsonObj.get("compId"));String modelId = String.valueOf(jsonObj.get("modelId"));List<Map> colList = this.mainResultService.findColListByModelId(compId, modelId);String queryParamStr = String.valueOf(jsonObj.get("queryParam"));Map queryParam = JSONUtil.fromJsonString(queryParamStr, Map.class);
//          fileName = new String(fileName.getBytes("iso8859-1"),"utf8");Map<String, Object> queryResult = this.tAmModelMainResultService.queryDetailList(queryParam);List<Map> list = (List<Map>) queryResult.get("data");final Workbook exportWorkbook = AmExcelHelpUtil.createWorkbook(fileType);exportWorkbook.createSheet(fileName);final CellStyle headCellStyle = exportWorkbook.createCellStyle();final CellStyle contentCellStyle = exportWorkbook.createCellStyle();final CellStyle contentCenterCellStyle = exportWorkbook.createCellStyle();final CellStyle contentRightCellStyle = exportWorkbook.createCellStyle();final Font headCellFont = exportWorkbook.createFont();final Font contentFont = exportWorkbook.createFont();final Sheet manuSheetNew = exportWorkbook.getSheetAt(0);manuSheetNew.setDefaultRowHeightInPoints((short) 25);manuSheetNew.setDefaultColumnWidth(25);final Row headRow = manuSheetNew.createRow(0); // 标题行int colCount = colList.size();for (int j = 0; j < colCount; j++) {final Cell cell = headRow.createCell(j);headCellStyle.setAlignment(CellStyle.ALIGN_CENTER);headCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);headCellStyle.setWrapText(true);headCellFont.setFontHeightInPoints((short)10);headCellFont.setFontName("微软雅黑");headCellFont.setBoldweight(Font.BOLDWEIGHT_BOLD);headCellStyle.setFont(headCellFont);headCellStyle.setBorderBottom(CellStyle.BORDER_THIN);headCellStyle.setBorderLeft(CellStyle.BORDER_THIN);headCellStyle.setBorderRight(CellStyle.BORDER_THIN);headCellStyle.setBorderTop(CellStyle.BORDER_THIN);headCellStyle.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);headCellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);cell.setCellStyle(headCellStyle);Map colMap = colList.get(j);String colCnName = String.valueOf(colMap.get("colcnname"));excelHelpUtil.setCellValue(fileType, manuSheetNew, 0, j, colCnName);}if (list != null && list.size() > 0) {int indx = 1;for (Map dataMap : list) {if (dataMap == null) {continue;}final Row row = manuSheetNew.createRow(indx);row.setHeightInPoints((short) 25);for (int j = 0; j < colCount; j++) {final Cell cell = row.createCell(j);Map colMap = colList.get(j);String colEnName = String.valueOf(colMap.get("colenname")).toLowerCase();String dataType = String.valueOf(colMap.get("coldatatype"));if ("1,2".contains(dataType)) {contentCenterCellStyle.setAlignment(CellStyle.ALIGN_CENTER);contentCenterCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentCenterCellStyle.setWrapText(true);contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentCenterCellStyle.setFont(contentFont);contentCenterCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderTop(CellStyle.BORDER_THIN);cell.setCellStyle(contentCenterCellStyle);} else if ("3".equals(dataType)) {contentRightCellStyle.setAlignment(CellStyle.ALIGN_RIGHT);contentRightCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentRightCellStyle.setWrapText(true);contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentRightCellStyle.setFont(contentFont);contentRightCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderTop(CellStyle.BORDER_THIN);cell.setCellStyle(contentRightCellStyle);} else {contentCellStyle.setAlignment(CellStyle.ALIGN_LEFT);contentCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentCellStyle.setWrapText(true);contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentCellStyle.setFont(contentFont);contentCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentCellStyle.setBorderTop(CellStyle.BORDER_THIN);cell.setCellStyle(contentCellStyle);}excelHelpUtil.setCellValue(fileType, manuSheetNew, indx, j, String.valueOf(dataMap.get(colEnName)));}indx++;}}exportWorkbook.write(byteArrayOut);exportBytes = byteArrayOut.toByteArray();resp.setStatus(200);resp.setContentType("application/x-download;charset=utf8");resp.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"",URLEncoder.encode(fileName + "." + fileType, "UTF-8")));resp.getOutputStream().write(exportBytes);} catch (IOException e) {e.printStackTrace();}}

原因分析:

  1. 大数据量导出应该使用poi 3.8以上提供的类SXSSFWorkbook,2007版 XSSFWorkbook不适用于数据量较大的数据导出。
  2. 创建样式对象时,应重复使用,不要每次填充cell时都新建一个样式对象。

解决方案:

/*** * @param req* @param resp* @param operParams*/@EcpGetMapping("/exportResultDetailForExcel")public void exportResultDetailForExcel(final HttpServletRequest req, final HttpServletResponse resp, @RequestParam final String operParams) {byte[] exportBytes = null;ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();SXSSFWorkbook exportWorkbook = null;try {JSONObject jsonObj = JSONObject.parseObject(operParams);String fileName = String.valueOf(jsonObj.get("fileName"));String fileType = String.valueOf(jsonObj.get("fileType"));String compId = String.valueOf(jsonObj.get("compId"));String modelId = String.valueOf(jsonObj.get("modelId"));List<Map> colList = this.mainResultService.findColListByModelId(compId, modelId);String queryParamStr = String.valueOf(jsonObj.get("queryParam"));Map queryParam = JSONUtil.fromJsonString(queryParamStr, Map.class);Map<String, Object> queryResult = this.tAmModelMainResultService.queryDetailList(queryParam);List<Map> list = (List<Map>) queryResult.get("data");exportWorkbook = new SXSSFWorkbook(2000);exportWorkbook.setCompressTempFiles(false);exportWorkbook.createSheet(fileName);final CellStyle headCellStyle = exportWorkbook.createCellStyle();final CellStyle contentCenterCellStyle = exportWorkbook.createCellStyle();final Font headCellFont = exportWorkbook.createFont();headCellStyle.setAlignment(CellStyle.ALIGN_CENTER);headCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);headCellStyle.setWrapText(true);headCellFont.setFontHeightInPoints((short)10);headCellFont.setFontName("微软雅黑");headCellFont.setBoldweight(Font.BOLDWEIGHT_BOLD);headCellStyle.setFont(headCellFont);headCellStyle.setBorderBottom(CellStyle.BORDER_THIN);headCellStyle.setBorderLeft(CellStyle.BORDER_THIN);headCellStyle.setBorderRight(CellStyle.BORDER_THIN);headCellStyle.setBorderTop(CellStyle.BORDER_THIN);headCellStyle.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);headCellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);final Font contentFont = exportWorkbook.createFont();//居中contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentCenterCellStyle.setAlignment(CellStyle.ALIGN_CENTER);contentCenterCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentCenterCellStyle.setWrapText(true);contentCenterCellStyle.setFont(contentFont);contentCenterCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentCenterCellStyle.setBorderTop(CellStyle.BORDER_THIN);//居右final CellStyle contentRightCellStyle = exportWorkbook.createCellStyle();contentRightCellStyle.setAlignment(CellStyle.ALIGN_RIGHT);contentRightCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentRightCellStyle.setWrapText(true);contentRightCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentRightCellStyle.setBorderTop(CellStyle.BORDER_THIN);contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentRightCellStyle.setFont(contentFont);//居左final CellStyle contentCellStyle = exportWorkbook.createCellStyle();contentCellStyle.setAlignment(CellStyle.ALIGN_LEFT);contentCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);contentCellStyle.setWrapText(true);contentFont.setFontHeightInPoints((short) 10);contentFont.setFontName("微软雅黑");contentCellStyle.setFont(contentFont);contentCellStyle.setBorderBottom(CellStyle.BORDER_THIN);contentCellStyle.setBorderLeft(CellStyle.BORDER_THIN);contentCellStyle.setBorderRight(CellStyle.BORDER_THIN);contentCellStyle.setBorderTop(CellStyle.BORDER_THIN);final Sheet manuSheetNew = exportWorkbook.getSheetAt(0);manuSheetNew.setDefaultRowHeightInPoints((short) 25);manuSheetNew.setDefaultColumnWidth(25);final Row headRow = manuSheetNew.createRow(0); // 标题行int colCount = colList.size();for (int j = 0; j < colCount; j++) {final Cell cell = headRow.createCell(j);   cell.setCellStyle(headCellStyle);Map colMap = colList.get(j);String colCnName = String.valueOf(colMap.get("colcnname"));excelHelpUtil.setSXSSFCellValue(fileType, manuSheetNew, 0, j, colCnName);}if (list != null && list.size() > 0) {int indx = 1;for (Map dataMap : list) {if (dataMap == null) {continue;}final Row row = manuSheetNew.createRow(indx);row.setHeightInPoints((short) 25);for (int j = 0; j < colCount; j++) {final Cell cell = row.createCell(j);Map colMap = colList.get(j);String colEnName = String.valueOf(colMap.get("colenname")).toLowerCase();String dataType = String.valueOf(colMap.get("coldatatype"));if ("1,2".contains(dataType)) {         cell.setCellStyle(contentCenterCellStyle);} else if ("3".equals(dataType)) {                              cell.setCellStyle(contentRightCellStyle);} else {                       cell.setCellStyle(contentCellStyle);}excelHelpUtil.setSXSSFCellValue(fileType, manuSheetNew, indx, j, String.valueOf(dataMap.get(colEnName)));}indx++;}}exportWorkbook.write(byteArrayOut);exportBytes = byteArrayOut.toByteArray();resp.setStatus(200);resp.setContentType("application/x-download;charset=utf8");resp.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"",URLEncoder.encode(fileName + "." + fileType, "UTF-8")));resp.getOutputStream().write(exportBytes);} catch (IOException e) {e.printStackTrace();} finally{if (exportWorkbook != null) {try {//删除磁盘上的文件deleteSXSSFTempFiles(exportWorkbook);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}}}/*** Returns a private attribute of a class* @param containingClass The class that contains the private attribute to retrieve* @param fieldToGet The name of the attribute to get* @return The private attribute* @throws NoSuchFieldException* @throws IllegalAccessException */public static Object getPrivateAttribute(final Object containingClass, final String fieldToGet) throws NoSuchFieldException, IllegalAccessException {//get the field of the containingClass instanceField declaredField = containingClass.getClass().getDeclaredField(fieldToGet);//set it as accessibledeclaredField.setAccessible(true);//access itObject get = declaredField.get(containingClass);//return it!return get;}/*** 删除缓存文件 Deletes all temporary files of the SXSSFWorkbook instance.* @param workbook* @throws NoSuchFieldException* @throws IllegalAccessException */public static void deleteSXSSFTempFiles(final SXSSFWorkbook workbook) throws NoSuchFieldException, IllegalAccessException {int numberOfSheets = workbook.getNumberOfSheets();//iterate through all sheets (each sheet as a temp file)for (int i = 0; i < numberOfSheets; i++) {Sheet sheetAt = workbook.getSheetAt(i);//delete only if the sheet is written by streamif (sheetAt instanceof SXSSFSheet) {SheetDataWriter sdw = (SheetDataWriter) getPrivateAttribute(sheetAt,"_writer");//如果exportWorkbook.setCompressTempFiles(true);//下一行代码就会报错File f = (File) getPrivateAttribute(sdw,"_fd");try {f.delete();} catch (Exception ex) {//could not delete the file}}}}

说明:由于poi 3.8 没有 dispose()方法,所以需要写清除硬盘上存的文件,poi 3.8以上就可以直接使用。
exportWorkbook = new SXSSFWorkbook(2000);
就是将超过2000条的数据存入到电脑磁盘上,2000以内的数据放入缓存中,这样就可以减少内存的占用。创建样式的话,不需要放在for循环中,这样就解决问题了,36万的数据只需要10几秒就导出完成,提高了导出的性能。

java POI导出excel性能优化相关推荐

  1. java poi 导出excel不能超过65536行

    java poi 导出excel不能超过65536行 报这个异常 Exception in thread "main" java.lang.IllegalArgumentExcep ...

  2. java poi导出Excel表格超大数据量解决方案

    Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果 ...

  3. Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框

    原文转载:http://blog.csdn.net/evangel_z/article/details/7332535 目录(?)[+] 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数 ...

  4. Java POI 导出EXCEL经典实现 Java导出Excel

    转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...

  5. Java POI导出Excel

    版权声明:本文为博主原创文章,未经博主允许不得转载.    在软件开发工作当中,导出Excel表格是比较常见的,下面我为大家分享一下POI导出Excel的一些方法. 1.引用poi.jar包 < ...

  6. JAVA POI 导出EXCEL时,EXCEL模板中的公式无效问题

    JAVA POI 出力EXCEL时,EXCEL模板中的公式无效问题 工作中遇到一个问题. EXCEL模板有两个sheet,画面内容要导出到第二个sheet中,第一个sheet设置公式,读取第二个she ...

  7. java poi 导出excel 数字有问题

    在用poi导出excel时 导出的数字为文本格式(左上角有绿色三角) 原因: cell.setCellType(Cell.CELL_TYPE_NUMERIC); cell.setCellValue( ...

  8. JAVA POI导出EXCEL设置自定义样式(线框加粗,合并指定行,合计求和,冻结行)

    前面部分是当时查询的记录: 实现Excel文件单元格合并.冻结和文件导出 Workbook wb = new HSSFWorkbook();Sheet sheet = wb.createSheet(& ...

  9. Java POI导出Excel时,合并单元格没有边框的问题

    今天用POI导出Excel的时候,发现导出的单元格确少边框,最后发现有2个方案可以解决. 方案一 CellRangeAddress的4个参数分别表示:起始行号,终止行号, 起始列号,终止列号 // 使 ...

  10. java poi 导出excel 速度慢_java POI技术之导出数据优化(15万条数据1分多钟)

    专针对导出excel2007 ,用到poi3.9的jar package com.cares.ynt.util; import java.io.File; import java.io.FileOut ...

最新文章

  1. 【Vegas原创】解决System.Web.Extensions版本冲突方法
  2. LeetCode Find All Numbers Disappeared in an Array
  3. 开源APM技术选型与实战
  4. css3新特性总结(视觉表现方面)
  5. AESNI/XData勒索病毒来袭 目前主要在乌克兰传播 它居然还能使用硬件加速加密过程...
  6. 在 Apache Spark 中利用 HyperLogLog 函数实现高级分析
  7. CentOS 7系统上部署Apache+PHP+MariaDB+xcache使用rpm,php module
  8. 光线跟踪的几种常见求交运算
  9. 对话哈佛大学教授Lukin:量子计算将在我们有生之年普及!
  10. 世界各国简称 电话区号JSON数据
  11. python自动化plc_PYTHON – 让“Monty 语言”进入自动化行业:第 4 部分
  12. 庆祝JavaCard技术领导SmartCard技术超过五年
  13. Flask项目实战——6—(前台用户模型、前台登录注册、图形验证码、手机短信验证码、添加表单验证短信验证码请求)
  14. 读书笔记:Python编程——从入门到实践
  15. hadoop配置、运行错误总结一
  16. 我的Android说
  17. Visual Studio 2019解决右侧工具栏消失
  18. 网络安全学习记录-9
  19. osgEarth示例分析——osgearth_imageoverlay
  20. Java-null(对空值得处理)

热门文章

  1. 幼儿园管理系统的设计与实现
  2. 单片机CC2530学习笔记
  3. Mysql中Regexp常见用法
  4. 万字长文干货,广告投放中常说的CPA、CPC、CPD、CPT、CPS、CPM、CPI是什么意思?
  5. 当软件定义汽车成为趋势,未来汽车是否可以理解为四个轮子上的超级计算机?
  6. 特征数据清洗 编码 标准化
  7. oracle not like优化,oracle的like优化,对比了一下,效果确实比like好些。
  8. Vasp学习专题之软件的基本功能和使用
  9. php工作流如何实现,工作流设计参考(包括PHP实现)
  10. Python入门之经典函数实例