JAVA导出上万行Excel数据的解决方案

    在Java Web开发中,经常需要导出大量的数据到Excel,动辄就上千,上万行的数据让我们的程序感觉压力很大,甚至都出现无法导出的情况,使用POI、JXL直接生成Excel,很容易就造成内存溢出了。即使不溢出,由于代码执行耗时太久也会长时间阻塞web页面,导致web系统并发访问性能急剧下降。

    怎么解决内存溢出问题呢?用POI处理的话,毕竟数据还是一次性在内存中进行保存的,数据量太大JVM就内存溢出了,这时我们想是不是可以导出多个Excel呢?

    沿着这个思路去想问题,首先我们要确定数据量有多大,然后确定一个Excel导出多少条数据,这样就可以确定导出的Excel的数量,于是我们就可以循环的导出Excel并保存在任意的临时目录中去,这样如果内存不够的话虚拟机就会去进行回收已经保存的Excel在内存中的空间。

    假设我们我们已经成功的生成了多个Excel,这时我们怎么把这N个Excel文档传到客户端展示呢?其实一个一个的传也未尝不可,但是考虑那样对用户来说体验不够好,用户保存一个个文件到本地再打开,再一个一个浏览或者打印很是不方便。

    用生成多个文件发送到客户端的方案增加了开发难度,生成文件的速度也更慢了。如果换一种方式,绕过JVM的内存限制问题应该怎么解决呢?可以在客户端生成文件。

    网上能找到几家做在线编辑office文件的产品,有的提供了js调用Office的VBA接口的对象,采用在客户端打开文件时,用js通过VBA接口把数据填充到Excel单元格中去生成文件,这样就绕过了服务器上内存溢出的问题,减轻了服务器的压力,是不是可行呢?经测试,此方式生成几千行数据的Excel表格速度就比较慢了,一旦上万行数据,执行效率就会急速降低甚至程序死掉。更为可怕的是,怎么把后台代码查询的数据集的上万行数据传递给前台页面的js,编程更痛苦。没有更好的方法了吗?也不是。

    本人最近研究了一个国产的商业软件PageOffice,本质上也是在客户端生成Excel表格的,但是这个产品提供的是服务器端的编程对象,接口很简单,调用起来比js舒服多了,通过对这个产品提供的服务器端Excel操作对象编程,客户端就能在用户需要Excel表格的时候实时生成,也同时解决了文件的在线预览和打印问题。PageOffice肯定是对Excel的接口做过深度优化的,本人测试的结果,填充上万行数据也能瞬间完成,还支持赋值公式、单元格样式和文本样式的设置(由于本人开发的项目中无需处理这些,对于这些功能没做研究,所以无法做深入的描述),所以在此与大家分享一下,有兴趣可以去PageOffice的官网下载一个试用版测试。


    附本人测试PageOffice导出2万行Excel表格的代码:

   Workbook wb = new Workbook();
  Sheet sheet1 = wb.openSheet("Sheet1");
  Table table = sheet1.openTable("B1:F2");
  for(int i=0; i<20000;i++) {
table.getDataFields().get(0).setValue (String.valueOf(i));//B列
table.getDataFields().get(1).setValue("测试");//C列
table.getDataFields().get(2).setValue("测试");//D列
table.getDataFields().get(3).setValue("测试");//E列
table.getDataFields().get(4).setValue("测试");//F列
table.nextRow();
}
table.close()

PageOfficeCtrl poCtrl1 = new PageOfficeCtrl(request);
poCtrl1.setServerPage("poserver.do"); //此行必须
poCtrl1.webOpen("doc/template.xlsx", OpenModeType.xlsSubmitForm, "");
poCtrl1.setTagId("PageOfficeCtrl1"); //此行必须

猜你喜欢

转载自liily.iteye.com/blog/1851221