日期:2014-05-20  浏览次数:20905 次

求助~~~关于jxl写大批量数据的Excel
对于jxl不是很熟悉,简单的写了个读文件出excel的程序。
  但是现在这样做法一旦数据量太大,缓存就爆掉了。请教大牛怎么样才能实现读取一部分数据,先写入Excel,然后再读一部分再写进去。
  当然有更好的方法就最好了~

Java code
package jxl;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class JxlExcelWriter {
    
    /**
     * @param out 输出excel文件.
     * @param br 输入txt文件.
     */
    public void writeExcel(OutputStream out, BufferedReader br) {
        if(br == null) {
            throw new IllegalArgumentException("写excel流需要file!");
        }
        try {
            WritableWorkbook workbook = Workbook.createWorkbook(out);
            WritableSheet ws = workbook.createSheet("sheet 1", 0);
            int rowNum = 0; // 写入行数
            
            //文件行数
            String line = null;
            while((line = br.readLine()) != null){
                String[] data = line.split("\t");
                Object[] cells = (Object[]) data;
                putRow(ws, rowNum, cells); // 写一行到sheet
                rowNum++;
               
            }
            
            workbook.write();
            workbook.close(); // 关闭、保存Excel
            
            System.out.print("success!");
        } catch (RowsExceededException e) {
            System.out.println("jxl write RowsExceededException: "+e.getMessage());
        } catch (WriteException e) {
            System.out.println("jxl write WriteException: "+e.getMessage());
        } catch (IOException e) {
            System.out.println("jxl write file i/o exception!, cause by: "+e.getMessage());
        }
    }

    private void putRow(WritableSheet ws, int rowNum, Object[] cells) throws RowsExceededException, WriteException {
        
        for(int i=0; i<cells.length; i++) {
            Label cell = new Label(i, rowNum, ""+cells[i]);
            ws.addCell(cell);
        }
    }
    
    public static void main(String args[]) {
        
        try {
            BufferedReader br = new BufferedReader(new FileReader("e:/input/data.txt"));
            OutputStream out = new FileOutputStream(new File("e:/out/test.xls"));
            
            JxlExcelWriter jxlExcelWriter = new JxlExcelWriter();
            jxlExcelWriter.writeExcel(out, br);
            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}



------解决方案--------------------
Object[] cells = (Object[]) data;
这数组爆了?

我用poi的处理方法是sheet row cell都是有一个就new一个,然后才插入,而不是先放入数组。
像03版本前的excel文件sheet单表最大是65535行,那就在行数进行判断,如果多于一个数,比如5W,那么就new一个新的sheet。这样创建过5-6M的Excel文件也没问题。
jxl应该也可以这么处理吧
------解决方案--------------------
无论是jxl还是poi都做不到楼主说的功能。
就算实现了,也属于“假分页”,因为你说你想分批写,也是要把数据load进内存的,这两个框架都无法分sheet(真正的写完后清内存数据)的。

不过,我们可以换位思考一下,一个excel, 65535行,如果真的写满了,谁去看呀?

这种需求就属于技术的bottleneck了,需要分excel写,即N条数据,按65535行数据为一个xls文件,写完后立望施放,然后再把剩余的数据写到另一个xls文件。

否则根本无法做到,因此需要从需求上去优化这个功能了。