java 大量数据导出为Excel 内存溢出

J2EE 码拜 10年前 (2015-05-10) 4640次浏览 0个评论

从数据库中按查询条件一次性获取大量数据,要把这些数据导出为Excel,当前超过8000左右就出现内存溢出,请问如何做到一次性导出5万条左右的数据。

如果是用poi或者jxl之类的,肯定会内存溢出
因为,它们都是一次在内存生成整个excel对象。
poi最新版本倒是支持excel2007写临时文件,但是2003不能用。
有一种做法就是不以excel的形式导出,如:Excel另存为XML格式,以此XML为模板,将需要导出的内容拼接为XML字符串按顺序写到一个后缀为xls的文件中。也能用Excel打开的,但是这种情况适用于导出的是数据列表,如果有公式、图表之类的就不适用了。这种方式导出几十W都没问题。
导出数据首先跟你的数据库有关系,一般数据库的游标没定义的话都是有一个上限的。
而后,你的内存溢出应该是查询时将数据一条条插入的时候游标没有清空,然后越来越多,应该没查询一次就清空一次。statement=null,你可以看看你查询用的什么方式,内存溢出基本上数据库没问题就是程序上的游标没控制好了,希望能帮到你
引用 2 楼 flying_lanying 的回复:

导出数据首先跟你的数据库有关系,一般数据库的游标没定义的话都是有一个上限的。
而后,你的内存溢出应该是查询时将数据一条条插入的时候游标没有清空,然后越来越多,应该没查询一次就清空一次。statement=null,你可以看看你查询用的什么方式,内存溢出基本上数据库没问题就是程序上的游标没控制好了,希望能帮到你

谢谢!
我的主要是导出时内存溢出,一条条数据不断写,最后内存溢出。
不知道你说的数据问题是否与这个问题有关,可不再详细一些。

引用 1 楼 uyerp 的回复:

如果是用poi或者jxl之类的,肯定会内存溢出。
因为,它们都是一次在内存生成整个excel对象。
poi最新版本倒是支持excel2007写临时文件,但是2003不能用。
有一种做法就是不以excel的形式导出,如:Excel另存为XML格式,以此XML为模板,将需要导出的内容拼接为XML字符串按顺序写到一个后缀为xls的文件中。也能用Excel打开的,但是这种情……

谢谢你的回答!
能再详细一点么?

额,说得已经很详细了呀。
说你有什么不清楚的吧?我可以针对你的问题说。
你可以创建一个xls文件,另存为xml电子表格2003的格式,用编辑器看看xml的格式,然后用io直接按照那种方式写试试,应该就可以了。那种格式用excel是可以打开的。或者你导出csv格式嘛。要么扩大内存试试
引用 楼主 huo_er 的回复:

从数据库中按查询条件一次性获取大量数据,要把这些数据导出为Excel,当前超过8000左右就出现内存溢出,请问如何做到一次性导出5万条左右的数据。
              
                  java
                  excel
                  大量,海量数据导出
                  内存溢出
……

我现在用POI的方式处理,在1W数量级上暂时是没有问题的。在大数量级的还没有试验过。
.xlsx结尾的。
现在有一个想法,能不能读的时候分批读,每次读一部分,写的时候定位写呢?
晚上回去试试。

不错啊

挺好的

路过看大神解答
引用 1 楼 uyerp 的回复:

如果是用poi或者jxl之类的,肯定会内存溢出。
因为,它们都是一次在内存生成整个excel对象。
poi最新版本倒是支持excel2007写临时文件,但是2003不能用。
有一种做法就是不以excel的形式导出,如:Excel另存为XML格式,以此XML为模板,将需要导出的内容拼接为XML字符串按顺序写到一个后缀为xls的文件中。也能用Excel打开的,但是这种情……

我之前的做法是将数据一次性写成Excel的格式,用的是 WritableWorkbook 和 WritableSheet。你的意思是我指定一个本地路径,然后再将数据以xml的格式写到该路径下的以.xls结尾的文件中,是么?

40分
引用 11 楼 huo_er 的回复:

引用 1 楼 uyerp 的回复:如果是用poi或者jxl之类的,肯定会内存溢出。
因为,它们都是一次在内存生成整个excel对象。
poi最新版本倒是支持excel2007写临时文件,但是2003不能用。
有一种做法就是不以excel的形式导出,如:Excel另存为XML格式,以此XML为模板,将需要导出的内容拼接为XML字符串按顺序写到一个后缀为xls的文件中。……

简而言之就是拼接符合Excel格式的XML字符串写到一个你想写到的地方,直接response中写到用户浏览器也可以啊。
你随便找个简单的Excel另存为XML,就能理解我说的了。
POI或者JXL的话把服务器内存占满,导死服务器是肯定会发生的,跟数据条数还有字段个数都有关系。如果不对导出请求做并发限制,那结果会更严重。
如果要跟踪内存占用情况的话用jprofile监控下内存,做下代码级优化,但是效果不会改善多少的。

http://iceher0.iteye.com/blog/1418484   poi可以支持大数据导出,你认真看看吧。
到处逗号分隔的CSV格式。
引用 3 楼 huo_er 的回复:

引用 2 楼 flying_lanying 的回复:导出数据首先跟你的数据库有关系,一般数据库的游标没定义的话都是有一个上限的。
而后,你的内存溢出应该是查询时将数据一条条插入的时候游标没有清空,然后越来越多,应该没查询一次就清空一次。statement=null,你可以看看你查询用的什么方式,内存溢出基本上数据库没问题就是程序上的游标没控制好了,希望能帮到你

……

你干脆把你查询出数据开始插入那段代码贴出来吧,让我们大家看看有什么问题,没估计错的话应该是游标没清空

大数据量导出Excel的方案 java 大excel文件(2)
大数据量导出Excel的方案 java 大excel文件
楼主问题解决没
fieldsList = appReader.queryForList(“Contract.exportContractList”,inDto);

parametersDto.put(“合同条数”, new Integer(fieldsList.size()));// 合计条数
ExcelExporter excelExporter = new ExcelExporter();
excelExporter.setTemplatePath(“/report/excel/app/contract.xls”);
excelExporter.setData(parametersDto, fieldsList);
excelExporter.setFilename(“合同项目表.xls”);
excelExporter.export(request, response);

溢出了  和你的情况一样吗  求指教

楼主在否,问题解决了么,我遇到同样的问题了。可否加好友QQ361666358   分享下成果

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明java 大量数据导出为Excel 内存溢出
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!