润乾报表百万级数据量导出EXCEL解决方案分析

1. 问题概述 
在web页面上显示的报表导出到excel文件里是一种很常见的需求, 润乾报表的类excel模型,支持excel文件数据无失真的导入导出, 然而,当数据量较大的情况下,就会遇到一些问题: 
1. 2003Excel本身的支持最多65535行数据 
2. 在这种大数据量的报表生成和导出中,要占用大量的内存,甚至内存溢出 
难点:1.数据量大,报表在运算成ireport对象时每个sheet页内存不释放,可能内存溢出. 
    2.即使能够运算完ireport对象再导出Excel的过程中内存不释放,可能内存溢出.

2 . 案例 
上海期货交易所 
上海唯智信息

3. 解决方案 
一. 对于数据超过了65535行的问题,很自然的就会想到将整个数据分块,利用excel的多sheet页的功能,将超出65535行后的数据写入到下一个sheet页中,即通过多sheet页的 
方式,突破了最高65535行数据的限定, 具体做法就是,单独做一个链接,使用JSP导出,在JSP上通过程序判断报表行数,超过65535行后分SHEET写入。这样这个问题就得以解决了 
二. 在这种大数据量的报表生成和导出中,要占用大量的内存,尤其是在使用TOMCAT的情况下,JVM最高只能支持到2G内存,则会发生内存溢出的情况。此时的内存开销 
主要是两部分,一部分是该报表生成时的开销,另一部分是该报表生成后写入一个EXCEL时的开销。由于JVM的GC机制是不能强制回收的,因此,对于此种情形,我们要改变一种方式: 
1. 将该报表设置起始行和结束行参数,在API生成报表的过程中,分步计算报表,比如一张20万行数据的报表,在生成过程中,可通过起始行和结束行分4-5次进行。这样,就 
降低了报表生成时的内存占用,在后面报表生成的过程中,如果发现内存不够,即可自动启动JVM的GC机制,回收前面报表的缓存 
2. 导出EXCEL的过程,放在每段生成报表之后立即进行,改多个SHEET页为多个EXCEL,即在分步生成报表的同时分步生成EXCEL,则通过 POI包生成EXCEL的内存消耗也得以降低。通过 
多次生成,同样可以在后面EXCEL生成所需要的内存不足时,有效回收前面生成EXCEL时占用的内存 
3. 再使用文件操作,对每个客户端的导出请求在服务器端根据SESSIONID和登陆时间生成唯一的临时目录,用来放置所生成的多个EXCEL,然后调用系统控制台,打包多个EXCEL为RAR 
或者JAR方式,最终反馈给用户一个RAR包或者JAR包,响应客户请求后,再次调用控制台删除该临时目录。 
4. 通过分段运算和生成,有效降低了报表从生成结果到生成EXCEL的内存开销。其次是通过使用压缩包,响应给用户的生成文件体积大大缩小,降低了多用户并 
发访问时服务器下载文件的负担,有效减少多个用户导出下载时服务器端的流量,从而达到进一步减轻服务器负载的效果

4. 程序部分 
1.JSP里导出的链接格式:<a href="<%=request.getContextPath()%>/exportToExcel.jsp?report=分页标签.raq&path=reportFiles\&param=arg1=123,234;arg2=2">导出Excel</a> 
也可用javascript的方式 
2.导出EXCEL中对于取最大行数,可以在报表里多定义一个数据集专门取最大行数,在后台通过API方式解析,保证通用性避免代码中出现SQL,复杂SQL,存储过程等,如图:


jsp具体代码: 
<%@ page contentType="text/html;charset=GBK"%> 
<%@ page import="com.runqian.report4.model.*"%
<%@ page import="com.runqian.report4.usermodel.*"%> 
<%@ page import="com.runqian.report4.view.excel.*"%> 
<%@ page import="com.runqian.report4.util.*"%<

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值