服务器有100万+条数据,要实现在客户端导出为Excel。现在我使用的是JXL,做法是客户端每次去服务器取100条数据,然后追加到现有文件中,如果第一次导出则创建文件,相关代码如下:originalWbook = Workbook.getWorkbook(file);//已经导出的
newWbook = Workbook.createWorkbook(file, originalWbook);//要追加新记录的问题是:每次从服务器获取新数据到客户端后,客户端在存文件时都要读取现有数据然后再追加,导致客户端内存占用量随着导出数据量的增加而快速增加,最终导致客户端OutOfMemoryError!请问大家有什么方法可以实现不用读取已存在的数据,直接将新数据追加到现有Excel文件中吗?不用JXL也可以。

解决方案 »

  1.   

    把JVM内存改大一点试试看
    分放在多个EXCEL文件中不行吗
      

  2.   

    崩溃就崩溃在write()方法是一次性写成Excel格式...
    我去看SRC...结果发现他给我的都是抽象类和抽象方法
    气的不行啊....
    不然你就得写100次了....
    我的想法是这样...不知道可以不....
    这样...你先
    originalWbook = Workbook.getWorkbook(file);
    WritableSheet sheet=originalWbook.getSheet(originalWbook.);
    int   location=sheet.getRows(getSheets()-1);
    然后就是把你读回来的对象分开...每个数据条生成一个cell对象...
    在用sheet.addCell 方法来写吧....(不过如果一个sheet太多CELL,会报出一个RowsExceededException  提醒你创建新的sheet)
    恩.......最后就关掉好了....
    好象只要是write调用就会,整个文件都重新调整格式(这话你参考就可以了...我也不知道...我是根据API猜的)
    希望能帮到你...我毕竟只是个小饼子
      

  3.   

    对不起
    纠正下上面的代码...
    实在抱歉
    originalWbook = Workbook.getWorkbook(file); 
    WritableSheet sheet=originalWbook.getSheet(originalWbook.getSheets()-1); 
    int   location=sheet.getRows(); 然后就是把你读回来的对象分开...每个数据条生成一个cell对象... 
    在用sheet.addCell 方法来写吧....(不过如果一个sheet太多CELL,会报出一个RowsExceededException  提醒你创建新的sheet) 
    恩.......最后就关掉好了.... 
      

  4.   

    你可以读一条记录,先判断是否已经读过了.如果读过了,就放弃,将其置为null,让gc去回收.
      

  5.   

    不好办,你还是增加你的JVM可用内存吧。默认的32M可能不够用了估计你是用批处理执行你的程序的,增加2个参数java -Xms128m -Xmx256m YourExcelApp param
      

  6.   

    To 陆烨辰:
    originalWbook.getSheet(originalWbook.getSheets()-1); 返回的结果是只读的,也就是只是Sheet,而不是WritableSheet,所以
    WritableSheet sheet=originalWbook.getSheet(originalWbook.getSheets()-1); 无法编译通过To 老紫竹:
    如果服务器100万条数据增加内存还可以,如果是1000万条或者更多呢?我觉得增加堆内存的方法也不是很好啊,而且现在的问题是随着导出数据的增加导出速度明显变慢,就是因为读写内存数据越来越大如果这个问题不能解决的话,我还不如每次去服务器取数据,直接放到客户端的内存中,免得每次拿回来数据还得读写文件,岂不是效率更高?
      

  7.   

    To 一任天然★IT民兵:
    如果实在没办法了就只能按你说的方法了,其实最好还是保存到一个文件中,也不知道一个Excel文件最大支持多少条数据
      

  8.   

    额...昨天晚饭边吃边看..给老师逮起来了...
    好象确实是....都说要新建才能重新写....
    似乎JXL是没什么别的实现方式了...
    真不好意思,没能帮到你
      

  9.   

    我觉得增加JVM内存也不可能解决类似问题,毕竟交互的数据都要经过内存,而内存无论怎么扩都不可能比数据增量要快我觉得唯一可行的就是分批读取,一次占用部分内存,多次达到数据经过内存传输过来的目的,但权衡考虑每次读如何记录上一次的位置,是否可以考虑用rowId之类的标识行数的来找到位置,另外还需要考虑数据条数太多,每次读都需要重连接,连接不断无法保证内存数据清空数据库一大,各种问题就暴露出来的,其实跟网页分页的经典讨论也满类似的,不知道是否可以借鉴一些经验呢,感觉很多问题原理都是类似的呵呵,也不能帮更多忙,希望你能找到更好的解决办法
      

  10.   

    如果对结果数据文件没有很特别的格式要求的话,
    建议直接IO写csv文件,你可以读一行写一行,
    写成excel文件肯定要爆内存的。
    而且excel最多只支持65536条记录