×
文章路径: Java

处理大数据量报表导出

发表于3年前(Dec 24, 2014 1:58:12 PM)  阅读 941  评论 0

分类: Java 案例

标签: poi 大数据导出

一、问题场景:

报表导出功能是很多系统常见的,java报表导出常用poi,jxl等jar包,笔者常用的是poi。使用这些开源jar包导出excel都很简单,网上随机找个例子就能用,可是一旦碰到导出的数据量很大的时候就出问题了。项目中有个报表导出功能,如果不选条件,可以将所有数据进行导出,现有数据量有20w,客户不愿分批导出,导出过程中经常报错,无法正常完成,笔者接手处理该问题。

二、问题分析:

1、查看代码,所有数据直接从数据库load进来,组成java实体,在开发库测试,开发库上只有3w多数据,就已经报内存溢出了,这是一个问题。

2、解决完这个问题后使用poi进行excel写入操作时,同样会报内存溢出,这时使用的是poi3.7,用的HSSFWorkbook。

3、excel本身有限制2003 是65536行,2007是1048576行。

三、解决问题:

1、首先所有数据load到内存中的做法肯定是不对的,内存再大总有限制,数据量一直在增长,总有扛不住的一天,所以数据必须分批查询,分批处理。实际情况中,笔者项目中这个统计sql极其复杂,查询效率十分低,分页查询sql每次需执行将近1分钟,当中业务笔者不熟,不敢动。使用分页导出时,有一个问题特别要注意,在导出过程中,如果有新的记录进来,必然会导致数据混乱,导出过程越长,出现该问题的几率越大。要避免这种情况就必须确保导出数据的不变性,一般情况下要指定时间基点,以当前时间为基点,之后的数据不处理。

2、excel2003本身限制记录数不能超过65536行,2007是1048576行,这个限制我们无法突破。首先笔者把poi更新到3.9,使用SXSSFWorkbook写入2007格式的excel。SXSSFWorkbook支持分批写入,内存中只保存当前数据。如果数据量超过100w的话,就只能分多个excel,压缩后提供用户下载了。

3、基于上面改进后,笔者模拟10w数据导出,出现超时错误,预计耗时14分钟,超过了weblogic默认的10分钟限制。这时只能采取异步下载,轮询进度,导出完成后再下载,至此问题基本解决。

该文主要是介绍处理思路,代码方面涉及比较多,笔者写了一整套处理通用导出的工具,包含报表模板导出工具,模仿Iterator写了一个分页工具,以后看情况有机会再整理。

发表评论