关于数据导出的一些经验总结,包括excel页面负载跟堆内存溢出
数据导出的基本思路
通过查询数据库中的数据,生成excel文件
@PostMapping("/exportExcelAll")public AjaxResult exportExcelAll(@RequestBody QueryBodys queryBodys,HttpServletResponse response)throws Exception{List<String> ids = zhUserService.getSonDepartment(queryBodys.getParentDepartment());List<CxdckExport> exportAllData = zhCxdckService.getExportAllData(queryBodys, ids);ExcelUtils excelUtils = new ExcelUtils();SXSSFWorkbook hssfWorkbook = new SXSSFWorkbook(60000);hssfWorkbook = excelUtils.exportExcel2(exportAllData, CxdckExport.class);// 文件默认下载到桌面String path = File.separator+"车险代查勘"+DateUtil.format(new Date(),"yyyy年MM月dd日HH时mm分ss秒")+".xls";File f = new File(path);if(f.exists()){f.mkdirs();}OutputStream stream = new FileOutputStream(f);hssfWorkbook.write(stream);hssfWorkbook.close();stream.close();System.out.println("导出文件已经结束");return AjaxResult.success(path);}
导出方法
public <T> HSSFWorkbook exportExcel1(List<T> dataList, Class<T> classType,String sheetName) throws Exception {Field[] declaredFields = classType.getDeclaredFields();List<String> headers = new LinkedList<>();List<String> variables = new LinkedList<>();HSSFWorkbook hssfWorkbook = new HSSFWorkbook();//创建sheetHSSFSheet hssfSheet = hssfWorkbook.createSheet();HSSFRow row = hssfSheet.createRow(0);hssfWorkbook.setSheetName(0, sheetName);int headerIndex = 0;//创建导入实体的字段名称for (Field field : declaredFields) {if (field.isAnnotationPresent(ExcelHeader.class)) {ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);headers.add(annotation.name());row.createCell(headerIndex).setCellValue(annotation.name());variables.add(field.getName());headerIndex += 1;}}//循环传入值for (int i = 0; i < dataList.size(); i++) {HSSFRow rowData = hssfSheet.createRow(i + 1);T t = dataList.get(i);Class<?> aClass = t.getClass();for (int j = 0; j < variables.size(); j++) {Field declaredField = aClass.getDeclaredField(variables.get(j));declaredField.setAccessible(true);String key = declaredField.getName();Object o = declaredField.get(t);if ("null".equals(String.valueOf(o))) {rowData.createCell(j).setCellValue("");} else {rowData.createCell(j).setCellValue(String.valueOf(o));}}}}hssfWorkbook.close();return hssfWorkbook;
注解反射的使用
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelHeader {String name() default "";int columnIndex() default 0;
}
//导入数据的实体
@Data
public class CxdckExport {/*** id*/private Long cxdckId;/*** 委托方名称*/@ExcelHeader(name = "委托方")private String cName;/*** 催收信息id*/private Long csInfoId;/*** 案件是否委托确认(0:是;1:否)*/private String caseClien;@ExcelHeader(name = "案件是否委托确认")private String caseClienName;/*** 案件是否可查询(0:是;1:否)*/private String caseCanQuery;@ExcelHeader(name="案件是否可查询")private String caseCanQueryName;/*** 不可查询原因*/@ExcelHeader(name="不可查询原因")private String queryReson;/*** 结案情况*/@ExcelHeader(name="结案情况")private String caseInfo;/*** 公估费录入情况*/@ExcelHeader(name="公估费录入情况")private String ggInfo;/*** 公估发票接受情况*/@ExcelHeader(name="公估发票接受情况")private String ggfpInfo;/*** 费用支付情况*/@ExcelHeader(name="费用支付情况")private String costInfo;/*** 是否有跟踪信息信息*/private String caseTrack;@ExcelHeader(name = "是否有跟踪信息")private String caseTrackName;/*** 日常表id*/private Long dailyId;/*** 反馈内容*/@ExcelHeader(name="反馈内容")private String feedback;/*** 委托单位名称*/@ExcelHeader(name = "委托单位名称")private String clientDepartment;/*** 委托单位联系人姓名*/@ExcelHeader(name = "委托单位联系人姓名")private String clientContactName;/*** 委托单位联系人电话*/@ExcelHeader(name = "委托单位联系人电话")private String clientContactPhone;/*** 委托人姓名*/@ExcelHeader(name = "委托人姓名")private String clientName;/*** 委托人身份证号码*/@ExcelHeader(name = "委托人身份证号")private String clientIdCard;/*** 委托人电话号码*/@ExcelHeader(name = "委托人电话号码")private String clientPhone;/*** 委托渠道名称*/@ExcelHeader(name = "委托渠道")private String clientChannelName;/*** 业务来源部门名称*/@ExcelHeader(name = "业务来源部门")private String businessSourceName;/*** 所属部门或事业部名称*/@ExcelHeader(name = "所属部门或事业部")private String fromDepartmentName;/*** 业务处理部门名称*/@ExcelHeader(name = "业务处理部门")private String businessProcessingDepartmentName;/*** 业务性质名称*/@ExcelHeader(name = "业务性质")private String businessNatureName;/*** 案件编号*/@ExcelHeader(name = "案件编号")private String caseNo;/*** 委托时间*/@ExcelHeader(name = "委托时间")private String clientTime;/*** 报案号*/@ExcelHeader(name = "报案号")private String toCaseNo;/*** 车牌号*/@ExcelHeader(name = "车牌号")private String carNo;/*** 票据号*/@ExcelHeader(name = "票据号")private String ticketNo;/*** 开票时间*/@ExcelHeader(name = "开票时间")private String ticketTime;/*** 开票人名称*/@ExcelHeader(name = "开票人")private String ticketPeopleName;/*** 开票金额*/@ExcelHeader(name = "开票金额")private BigDecimal ticketAmount;/*** 开票单位*/@ExcelHeader(name = "开票单位")private String ticketDepartment;/*** 开票状态名称*/@ExcelHeader(name = "开票状态")private String ticketStatusName;/*** 到账金额*/@ExcelHeader(name = "到账金额")private BigDecimal amountReceived;/*** 到账日期*/@ExcelHeader(name = "到账日期")private String receivedDate;/*** 核销时间*/@ExcelHeader(name = "核销时间")private String writeOffTime;/*** 催收日常序号*/@ExcelHeader(name="催收日常序号")private String infoId;/*** 跟踪时间*/@ExcelHeader(name="跟踪时间")private String trackTime;/*** 跟踪人*/@ExcelHeader(name="跟踪人")private String track;/*** 催收日常反馈*/@ExcelHeader(name="催收日常反馈")private String dailyFeedback;/*** 催收日常备注*/@ExcelHeader(name="催收日常备注")private String note;
}
bug的解决
1.关于excel的单sheet最大限制65535行
通过循环多sheet解决
public <T> HSSFWorkbook exportExcel1(List<T> dataList, Class<T> classType,HSSFWorkbook hssfWorkbook) throws Exception {Field[] declaredFields = classType.getDeclaredFields();List<String> headers = new LinkedList<>();List<String> variables = new LinkedList<>();//HSSFWorkbook hssfWorkbook = new HSSFWorkbook();if(dataList.size()/50000 > 0){for(int m = 1;m <= dataList.size()/50000+1;m++){HSSFSheet hssfSheet = hssfWorkbook.createSheet();HSSFRow row = hssfSheet.createRow(0);// hssfWorkbook.setSheetName(0, sheetName);int headerIndex = 0;for (Field field : declaredFields) {if (field.isAnnotationPresent(ExcelHeader.class)) {ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);headers.add(annotation.name());row.createCell(headerIndex).setCellValue(annotation.name());variables.add(field.getName());headerIndex += 1;}}for (int i = 50000*(m-1); i < 50000*m && i<dataList.size(); i++) {HSSFRow rowData;if(m != 1){;rowData = hssfSheet.createRow(i%(50000*(m-1)) + 1);}else {rowData = hssfSheet.createRow(i+1);}T t = dataList.get(i);Class<?> aClass = t.getClass();for (int j = 0; j < variables.size(); j++) {Field declaredField = aClass.getDeclaredField(variables.get(j));declaredField.setAccessible(true);String key = declaredField.getName();Object o = declaredField.get(t);if ("null".equals(String.valueOf(o))) {rowData.createCell(j).setCellValue("");} else {rowData.createCell(j).setCellValue(String.valueOf(o));}}}}}else {HSSFSheet hssfSheet = hssfWorkbook.createSheet();HSSFRow row = hssfSheet.createRow(0);// hssfWorkbook.setSheetName(0, sheetName);int headerIndex = 0;for (Field field : declaredFields) {if (field.isAnnotationPresent(ExcelHeader.class)) {ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);headers.add(annotation.name());row.createCell(headerIndex).setCellValue(annotation.name());variables.add(field.getName());headerIndex += 1;}}for (int i = 0; i < dataList.size(); i++) {HSSFRow rowData = hssfSheet.createRow(i + 1);T t = dataList.get(i);Class<?> aClass = t.getClass();for (int j = 0; j < variables.size(); j++) {Field declaredField = aClass.getDeclaredField(variables.get(j));declaredField.setAccessible(true);String key = declaredField.getName();Object o = declaredField.get(t);if ("null".equals(String.valueOf(o))) {rowData.createCell(j).setCellValue("");} else {rowData.createCell(j).setCellValue(String.valueOf(o));}}}}hssfWorkbook.close();return hssfWorkbook;}
2.关于导入数据过多致使堆内存溢出
解决的办法是将HSSFWorkbook替换成SXSSFWorkbook,
//SXSSFWorkbook可以设置内存的最大阈值,内存中的对象数量最大值,超过这个值会生成一个临时文件存放到硬盘中,这样就不会报堆内存溢出异常
SXSSFWorkbook sx = new SXSSFWorkbook(60000);
修改代码如下
public <T> SXSSFWorkbook exportExcel2(List<T> dataList, Class<T> classType) throws Exception {Field[] declaredFields = classType.getDeclaredFields();List<String> headers = new LinkedList<>();List<String> variables = new LinkedList<>();SXSSFWorkbook hssfWorkbook = new SXSSFWorkbook();if(dataList.size()/50000 > 0){for(int m = 1;m <= dataList.size()/50000+1;m++){SXSSFSheet hssfSheet = hssfWorkbook.createSheet();SXSSFRow row = hssfSheet.createRow(0);//hssfWorkbook.setSheetName(0, sheetName);int headerIndex = 0;for (Field field : declaredFields) {if (field.isAnnotationPresent(ExcelHeader.class)) {ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);headers.add(annotation.name());row.createCell(headerIndex).setCellValue(annotation.name());variables.add(field.getName());headerIndex += 1;}}for (int i = 50000*(m-1); i < 50000*m && i<dataList.size(); i++) {SXSSFRow rowData;if(m != 1){;rowData = hssfSheet.createRow(i%(50000*(m-1)) + 1);}else {rowData = hssfSheet.createRow(i+1);}T t = dataList.get(i);Class<?> aClass = t.getClass();for (int j = 0; j < variables.size(); j++) {Field declaredField = aClass.getDeclaredField(variables.get(j));declaredField.setAccessible(true);String key = declaredField.getName();Object o = declaredField.get(t);if ("null".equals(String.valueOf(o))) {rowData.createCell(j).setCellValue("");} else {rowData.createCell(j).setCellValue(String.valueOf(o));}}}
// hssfWorkbook.close();}}else {SXSSFSheet hssfSheet = hssfWorkbook.createSheet();SXSSFRow row = hssfSheet.createRow(0);//hssfWorkbook.setSheetName(0, sheetName);int headerIndex = 0;for (Field field : declaredFields) {if (field.isAnnotationPresent(ExcelHeader.class)) {ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);headers.add(annotation.name());row.createCell(headerIndex).setCellValue(annotation.name());variables.add(field.getName());headerIndex += 1;}}for (int i = 0; i < dataList.size(); i++) {SXSSFRow rowData = hssfSheet.createRow(i + 1);T t = dataList.get(i);Class<?> aClass = t.getClass();for (int j = 0; j < variables.size(); j++) {Field declaredField = aClass.getDeclaredField(variables.get(j));declaredField.setAccessible(true);String key = declaredField.getName();Object o = declaredField.get(t);if ("null".equals(String.valueOf(o))) {rowData.createCell(j).setCellValue("");} else {rowData.createCell(j).setCellValue(String.valueOf(o));}}}
// hssfWorkbook.close();}return hssfWorkbook;}
至此问题解决,有问题求指出
关于数据导出的一些经验总结,包括excel页面负载跟堆内存溢出相关推荐
- python 查询mysql数据导出excl_python查询mysql并生成excel表
需求说明 开发不愿意单独为某个项目做后台 并且运营那边需要合并多个表的数据 因此找上了我. 要求每周执行一次.月初也执行一次 要查询2个mysql数据库多个表并生成excel表 我的想法 找开发要sq ...
- c 传图片数据给matlab,c++ - 如何通过UDP将数据从C ++应用程序发送到Matlab并进行绘制 - 堆栈内存溢出...
我想使用Winsock通过UDP将数据从我的C ++应用程序发送到Matlab,并实时绘制数字. 例如:我得到了从1到10的数字,我想从C ++发送1,在Matlab中接收它,将其放在图形上(图,条等 ...
- 数据导出组件Data-Export:数据分析处理“加速器”
数据治理通用组件WeBankBlockchain-Data当前的3个子组件--数据仓库组件Data-Stash.数据导出组件Data-Export.数据对账组件Data-Reconcile,相互独立. ...
- 使用POI进行数据导出excel时的OOM服务挂掉,cpu飙升的问题
在日常工作中,经常可能会使用到poi来进行数据导出,但是在导出的过程中,如果对poi类使用不当,则可能会出现一些问题,比较严重,下面对poi中三种不同的类来进行说明. 1. HSSFWorkbook( ...
- php excel 导出超时,PHP数据导出超时、内存不足的解决
实际工作中,我们经常导出报表的需求,当导出数据量过大的时候,经常会遇到超时和内存溢出的问题. 解决方案一 超时可用: set_time_limit(0) 解决. 内存溢出可用: ini_set('me ...
- 数据库超10万数据导出Excel
ps: 首先科普一下基础知识 Excel 2003及以下的版本.一张表最大支持65536行数据,256列.也就是说excel2003完全不可能满足百万数据导出的需求. Excel 2007-2010版 ...
- 关于数据导出超时的问题
实际工作中,我们经常导出报表的需求,当导出数据量过大的时候,经常会遇到超时和内存溢出的问题. 解决方案一 超时可用: set_time_limit(0) 解决. 内存溢出可用: ini_set('me ...
- 使用phpspreadsheet导出数据时内存溢出处理
使用phpspreadsheet进行导出excel的时候遇到了内存溢出的问题,官方提供了memory saving的解决方案,官方文档中提供了APCu.redis和memcache的缓存方案,但是在这 ...
- java实现导出excel表_java实现导出网页中的表格为Excel
将网页中的table数据,导出到excel表格,可以使用java POI实现. java poi是java中操作excel的工具,支持excel的导入与导出,一般有三种形式: 1.HSSFWorkbo ...
最新文章
- maven scala plugin 实现jvmArgs,执行过程原理解析笔记
- jquery-autocomplete 使用手册
- C语言实现x的n次方
- Java final 关键字简述
- ajax+MultipartFile上传文件到本地
- 三台服务器无需密码相互访问
- SAP License:实例讲解SAP与金税接口
- Cordova+Vue实现Android APP开发
- distpicker省市区插件设置请选择省市区提示/或设置初始值问题
- c语言验证费马大定理,数论概论 第四章 高次幂之和与费马大定理 习题解答(宋二娃的BLOG)...
- python io操作不被打断_PyAPNs抛出IOError操作不受devi支持
- win10除去桌面图标小箭头(绝对没有坑!!!)与 该文件没有与之关联的程序来执行该操作。。。
- wustoj1296
- 新年喜报!10人通过RHCA、60人通过RHCE!
- GridControl应用点滴之选中数据行事件
- Net start 命令详
- 多线程---和尚吃馒头问题
- 一个农民工自学java找到工作的励志故事
- 用java语言编写程序计算九宫图
- mysql ddl ddm_数据库ddl ddm
热门文章
- 基于SpringBoot+Vue开发的前后端分离人力资源管理系统
- 1.1跟我一起学运维相关知识------[系统篇]
- Unity中贴图制作备忘录
- java使用Apache poi根据word模板生成word报表(增加插入符号、控制分页功能)
- ortc和webrtc
- IDEA设置主题和背景图片
- RS-485总线电平异常解决方案解析
- 算法与数据结构学习(8)-双向链表分析
- 我快 30 了,前途在哪里?
- win8.1开启系统打印服务器,Win8.1系统怎么打开打印机服务? win8怎么添加打印机...