做excel导出,数据很多,列也很多。估计现在行*列的值在140万,以后会更加的多。由于项目要求,必须全部导出表中的数据。但我用jxl发现,当数据多时,会报OutOfMemory的错误。我做过一个test测试,jxl处理500000没有问题,但处理1000000就会出现OutOfMemory错误了。
可以肯定是jxl的问题,但我不明白怎么jxl没有对象释放的方法呢???
测试代码:
jxl.write.WritableWorkbook wwb = null;
jxl.write.Label labelC = null;try {
wwb = Workbook.createWorkbook(new File("c:\\1.xls"));
for(int i=0;i<50000;i++) {
wwb = Workbook.createWorkbook(os);
for(int j=0;j<100;j++) {
labelC = new jxl.write.Label(j, i, "This is a Label cell1");
}
}
wwb.write();}
catch (Exception e)
{
System.out.println(e);
}
finally {
try {
os.close();
wwb.close();
}
catch(Exception e) {
System.out.println(e);
}
}
可以肯定是jxl的问题,但我不明白怎么jxl没有对象释放的方法呢???
测试代码:
jxl.write.WritableWorkbook wwb = null;
jxl.write.Label labelC = null;try {
wwb = Workbook.createWorkbook(new File("c:\\1.xls"));
for(int i=0;i<50000;i++) {
wwb = Workbook.createWorkbook(os);
for(int j=0;j<100;j++) {
labelC = new jxl.write.Label(j, i, "This is a Label cell1");
}
}
wwb.write();}
catch (Exception e)
{
System.out.println(e);
}
finally {
try {
os.close();
wwb.close();
}
catch(Exception e) {
System.out.println(e);
}
}
最好不要在for循环中用new运算符,尽量用赋值进行替代
将for(int j=0;j<100;j++)改为 for(int j=0;j<100;++j) 或 由递增改为递减
在操作N次后或是隔N久后进行一下System.gc() [n自定,视内存测试结果而定]
labelC = new jxl.write.Label(j, i, "This is a Label cell1");
ws.addCell(labelC); --问题的原因,加入的对象太多
但好像jxl没有提供ws.clear()释放对象的函数哦
labelC = null;有利于系统及时有效地回收垃圾。适当调用System.gc()也是很有效的。
wwb = Workbook.createWorkbook(os);//这句生成的是什么
wwb = Workbook.createWorkbook(new File("c:\\1.xls"));//这句生成的是什么
jxl.write.WritableWorkbook wwb = null;
jxl.write.Label labelC = null;
jxl.write.WritableSheet ws = null;
int iCount = 0;
try {
wwb = Workbook.createWorkbook(new File("c:\\1.xls"));
ws = wwb.createSheet("Test Sheet 1", 0);
for(int i=0;i<50000;i++) {
if(iCount>5000) {
iCount=0;
labelC = null;
System.gc();
}
for(int j=0;j<100;j++) {
labelC = new jxl.write.Label(j, i, "This is a Label cell1");
ws.addCell(labelC);
}iCount++;}
wwb.write();
}
catch (Exception e)
{
System.out.println(e);
}
finally {
try {
wwb.close();
}
catch(Exception e) {
System.out.println(e);
}
}
ws.addCell(labelC); 只符labelC = null,其实ws对象根本还没有清空。
iCount=0;
labelC = null;
System.gc();
}
----------------------------
我倒……
把labelC = null;放在这里,有意义???
//下面滴可能只会起部分作用,恐怕不会从根本上改变局面,必竟内存是有限滴for(int i=0;i<50000;++i)
{
if(iCount>5000)//根据内存测试结果进行调整为宜
{
iCount=0;
System.gc();
}
for(int j=0;j<100;++j)
{
ws.addCell(new jxl.write.Label(j, i, "This is a Label cell1"));
//也可用下面滴,不知效果会如何
//labelC = null;
//labelC = new jxl.write.Label(j, i, "This is a Label cell1");
//ws.addCell(labelC);
}
iCount += 1;
}
for(int i=0;i<50000;++i)
{
for(int j=0;j<100;++j)
{
ws.addCell(new jxl.write.Label(j, i, "This is a Label cell1"));
//也可用下面滴,不知效果会如何
//labelC = null;
//labelC = new jxl.write.Label(j, i, "This is a Label cell1");
//ws.addCell(labelC);
}
System.gc();
}
labelC只不过是依次指向各个jxl Label的句柄而已
将它置null或者主动调用gc()过程都是徒劳的在没有执行wwb.write()之前有没有生成文件?
个人认为,jxl对于大数据量的导入导出还是存在缺点的,支持5M的数据一次导入导出,但因为jxl提供的write()只能提交一次,而开大内存,个人认为确实可以解决问题,但显然不佳,我导100多万条数据出来,既然要150M的内存,如果用排版函数,内存更多。有时间研究一下它的代码。