现在网上基本方法是:
1.使用CSV下载。
2.调大JVM ,Tomcat的内存。目前这两种方法客户都不同意,大家还有什么方法吗?

解决方案 »

  1.   

    最终用户要求一个sheet容纳所有数据,如何融合之前导出的多个sheet?
      

  2.   

    Excel 2010 和 Excel 2007 中 (即xlsx格式)工作表的大小为 16,384 列 × 1,048,576 行。
    不知道能不能满足要求,不能的话就txt保存,不过可能文件过大,打开较慢
      

  3.   


    那应该也不难。你可以每次都加载那一个Excel文件,并加载第一个Sheet,分页加载的数据每次都从这个Sheet的最后一行开始添加,这样就OK了。
      

  4.   


    大哥,先读后写,文件越搞越大,POI还是把以前的内容读进去了,最后还是溢出。
    我试下2万行还可以,三万就不行。我的目标是6万,你有办法吗?
      

  5.   


    我觉得内存溢出是因为加载了太多的Model,而非加载Excel文件导致的。
    一个Excel文件才多大啊。我曾经加载过一个3G左右的电影文件都没有问题。
      

  6.   

    或者你不要把数据封装成Model,直接使用jdbc的ResultSet来填空Excel应该也不会内存溢出的。
      

  7.   


    这句话能否延伸一下,不太明白。另外数据嘛,我是取出来放list,别说六万,十万行都没有报溢出错。异常是在用POI做Excel文件时产生的。
      

  8.   


    对了,你要先确定是Java报的内存溢出,而不是数据库报的内存溢出,Oracle加载的数据多的话也可能报内存溢出的。如果是Java报的内存溢出,那么就按我的思路解决应该就可以。你用的是Hibernate之类的框架,查询出来一个List的吧。List里边存放的是封装的Java对象,是这样吗?
      

  9.   

    管理hibernate的缓存机制,hibernate的session中有flush,clear等方法,可以让内存消耗小一点
      

  10.   

    楼上两位,我已经在使用模拟数据,不走后台了。但还是过不了28000这关口,更别提60000了。数据生成过程从来不报异常,java.lang.OutOfMemoryError: Java heap space全是在生成Excel时出来的。
    我尝试过了用循环直接生成,分段生成不断读写文件两种方式,总是回报java.lang.OutOfMemoryError: Java heap space这个异常。
      

  11.   

    可以生成多个临时excel文件。。然后合并成一个excel文件。。写一个合并的类
      

  12.   


    我首先参考了网上的方案,但他是基于POI3.1的,到我的POI3.5中好多API不可用了。如前所述,我采用分段方式后,生成了临时文件,再进行合并时发现目标文件会越来越大,最终还是导致了溢出。
      

  13.   

    这问题 哥曾经遇到过,客户非要所有的数据都导出来,有时候数据量很大,甚至超过了EXCEL的最大行数,实在变态,后来的思路是:分割成多个小EXCEL文件,然后用Java的 ZIP类库的方法压缩成XXX.zip文件导出下载。
      

  14.   


    大哥,这么干客户是不会同意的。
    他们需要这样的解决方案:
    1.一个XLS文件下载。
    2.若数据少于6万行,只做成一个Sheet。
    3.大于6万行,以6万为单位分Sheet存放。可惜小弟目前还只在26000行左右徘徊。
      

  15.   

    这个问题我也研究过,最终也是生成多个excel文件打zip包得。内存溢出的原因是由于数据量太大了,说白了就是由于创建的cell对象太多了,导致内存溢出,我没有找到更好的解决方案,jxl也可以导出excel,不过会不会溢出,不过excel2003最大行数为65535,你的数据量如果溢出的话,还是需要生成2007的。
      

  16.   

    不知楼主的数据库支持导出数据位excel不,如果支持的话,可以先讲数据插入临时表,然后导出。这个方法有点烂。
      

  17.   

    或者楼主可以构造一个文件命名为xxx.xls,然后内容写<table>
    <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
    <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
    <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
    <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
    </table>
    不知道他们用这个excel数据还做后续操作不,如果只是看看,这样可以吧。
      

  18.   


    还有一个操作是读取进来,也是用POI。晕啊。
      

  19.   

    刚好前段时间我也研究过这个问题,问过一些人,但无论是poi还是jxl,貌似都没有办法解决的
    制成excel无论怎么操作最后都是统一优先load到内存最后写进去,这时候数据量大就会爆掉。
    只有一种变相的解决办法就是满多少数据重新生成一个临时excel最后再合并,但我不知道怎么实现
      

  20.   

    CSV吧。。
    不同意就让他们自己去搞。
      

  21.   

    我以前也遇到过这种问题,poi生成excel文档确实有数据量的问题,也是在28000行左右的数据,超过一定量的数据,必然会有这样的问题。
    当时的解决办法是改成csv,别的没办法。
      

  22.   

    1.一个XLS文件下载。
    2.若数据少于6万行,只做成一个Sheet。
    3.大于6万行,以6万为单位分Sheet存放。
    就是读到的数据不放入list,直接放到cell里呀,只是生成时间有点长罢了。
    10W条的数据大概要20多S,就用poi。
      

  23.   


    数据库查出来直接放cell,还能容纳10W条而不出溢出错?太强了,给代码看看呗。
      

  24.   


    这种方法我还真没试过,楼主试下发个结论出来。
    不知道微软自己如何搞的,楼主找找有木有c语言导出excel的例子,如果有的话,可以封装成dll用jni调用试试。
      

  25.   

    可能很土,但确实是不会溢出,共同提高吧
    一个cell一个cell的new呀,为什么会溢出呢?import java.sql.ResultSet;
    import java.sql.SQLException;import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;public class infoExportExcel {
    /**
     * 
     * @param intRowCount 总行数
     * @param sheetCount 一个sheet表内的行数
     * @param wb excel
     * @param sheetname sheet表名
     * @param columNumber 列数
     * @param tableHeader 表头名
     * @param rs 查询结果集
     * @throws SQLException
     */
    public infoExportExcel(int intRowCount, int sheetCount, HSSFWorkbook wb, String sheetname, int columNumber, String[] tableHeader, ResultSet rs) throws SQLException{
    int allSheetCount = (intRowCount + sheetCount -1)/sheetCount; //计算总工作表数,分表
    if(allSheetCount  > 1){   //分多个sheet表来显示
    int q = 0;//sheet数
    while(q < allSheetCount ){
    HSSFSheet sheet = wb.createSheet(sheetname + q); //sheet表名依次为表0、表1、表2...
    HSSFRow rowHeader = null;//表头
    rowHeader = sheet.createRow(0);
    for(int u = 0; u < columNumber; u++){
    HSSFCell headerCell = rowHeader.createCell(u);
    headerCell.setCellValue(tableHeader[u]);
    }
    int p = 1; //行
    HSSFRow rowData = null;//表内容
    while(rs.next() && p < sheetCount){
    rowData = sheet.createRow(p);
    HSSFCell cellData = null;
    for(int j = 0; j < columNumber; j++){
    cellData = rowData.createCell(j);
    cellData.setCellValue(rs.getString(j + 1));
    }
    p++;
    if(p > sheetCount){//大于行数后,下一个sheet表从1继续开始
    p = 1;
    }
    }
    q++;
    }
    }else{
    HSSFSheet sheet = wb.createSheet(sheetname);
    HSSFRow rowHeader = null;
    rowHeader = sheet.createRow(0);
    for(int u = 0; u < columNumber; u++){
    HSSFCell headerCell = rowHeader.createCell(u);
    headerCell.setCellValue(tableHeader[u]);
    }
    int p = 1;
    HSSFRow rowData = null;

    while(rs.next() && p < (intRowCount + 1)){

    rowData = sheet.createRow(p);
    HSSFCell cellData = null;
    for(int j = 0; j < columNumber; j++){
    cellData = rowData.createCell(j);
    cellData.setCellValue(rs.getString(j + 1));
    }
    p++;
    }
    }
    }}
      

  26.   

    不理解楼上代码为何不会溢出,难道是POI需要时间去释放内存?另外我发现读取一个5W多行的XLS没有问题,问题可能不是出在读取这里。
      

  27.   


    请问你一个Sheet中最多能放多少行?
      

  28.   

    你不是说导出excel下载出现问题么?怎么又读取了= =~~
    你觉得哪里有问题?这个代码在我这里没问题呀,之前写的时候没想过那么多条,后来要求分表显示的时候才加上了一个判断,可以正确导出
      

  29.   

    昨天试的时候只是5q 1W 和5W,都可以  
      

  30.   

    TO lxwankkk:
    1.请问你设置服务器内存大小了吗?
    2.>>你不是说导出excel下载出现问题么?怎么又读取了= =~~
      这个我是去测试读一个大文件会不会发生溢出现象。3.>>你觉得哪里有问题?这个代码在我这里没问题呀,之前写的时候没想过那么多条,后来要求分表显示的时候才加上了一个判断,可以正确导出
      问题就在这里了,不能理解为何先读到一个List再输出XLS会错 而 读出记录后直接写就没有问题。
      

  31.   

    1,没有
    3,嗯,年前好像也跟人讨论过这个问题,他也是先放到list里,然后就会报溢出。好像就是21楼吧。
    嗯,可能还是哪里有限制吧。
      

  32.   

    我生成结束后把list清理掉发现数据量上了30000,以上还没试过。等会我尝试一下取得记录就输出的情况。
      

  33.   

    刚才试了一下取得记录就输出的方式,数据量能提高到35000,但4W还是到不了。代码如下:
    Servlet代码:public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 56890894234786L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, java.io.IOException {
    String fileName="download.xls";
            response.setHeader("Content-disposition", "attachment; filename="+fileName);// 设定输出文件头   
            response.setContentType("application/msexcel");// 定义输出类型 
            
            try{
             int rowCount=Integer.parseInt(request.getParameter("rowCount"));
            
             // 表头行
             String[] headers=new String[]{"更新ID","账期","基站编号","基站名称","站点状态","部门名称","站点类型","占用类型","预提(元)","未核销金额","上期未核销","开始月份","结束月份","上期抄表数","本期抄表数","电价","电量","本期报账(元)","补提(元)","预提汇总(元)","成本中心","专业","本期报账单号","基站类别","线损"};
             DownloadService service=new DownloadService();         HSSFWorkbook workbook=service.generateWorkbook(rowCount, headers.length);
            
            // 输出部分
         OutputStream os = response.getOutputStream();// 取得输出流   
            workbook.write(os);
            os.flush();
            os.close();
            
            }catch(Exception ex){
             ex.printStackTrace();
            }

    return ;
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, java.io.IOException {
    doPost(request, response);
    }
    }Service代码:public class DownloadService{
    /**
     * 生成工作簿对象
     * @param rowCount
     * @param columnCount
     * @return
     */
    public HSSFWorkbook generateWorkbook(int rowCount,int columnCount){
    HSSFWorkbook workbook = new HSSFWorkbook(); //产生工作簿对象
    HSSFSheet sheet = workbook.createSheet(); //产生工作表对象
    String value=null;

    for(int i=0;i<rowCount;i++){
    HSSFRow row = sheet.createRow(i);//创建一行

    for(int j=0;j<columnCount;j++){
    value=""+i+","+j;

    HSSFCell cell = row.createCell(j);
    cell.setCellValue(value);
    cell=null;
    }
    }

    return workbook;
    }
    }
      

  34.   

    跟输入输出流有关系么,我用的这个ServletOutputStream out = response.getOutputStream();
    BufferedOutputStream bos = new BufferedOutputStream(out);
    wb.write(bos);
      

  35.   

    这个错误如蛆跗骨一般。java.lang.OutOfMemoryError: Java heap space
    at org.apache.poi.poifs.storage.DocumentBlock.<init>(DocumentBlock.java:84)
    at org.apache.poi.poifs.storage.DocumentBlock.<init>(DocumentBlock.java:70)
    at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:158)
    at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:182)
    at org.apache.poi.poifs.filesystem.DirectoryNode.createDocument(DirectoryNode.java:309)
    at org.apache.poi.poifs.filesystem.POIFSFileSystem.createDocument(POIFSFileSystem.java:265)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1157)
    at com.heyang.action.DownloadServlet.doPost(DownloadServlet.java:47)
    at com.heyang.action.DownloadServlet.doGet(DownloadServlet.java:60)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
    at java.lang.Thread.run(Unknown Source)
      

  36.   

    呵呵,这个我也遇到过。
    我这边的做法是excel压缩成zip,然后下载。
    因为我这边excel内容的特殊性,压缩后可以减少非常大的空间
      

  37.   

    或许可以这样试试,你读取3万行的时候断开下,然后重新读取输出!就像ODBC好像超过300连接就会报错
      

  38.   

    不才啊,我现在也遇到这个问题了,将EXCEL中的10W左右记录导入数据库中,报错啊。
    java.lang.OutOfMemoryError: Java heap space
    大家一起研究研究,该如何解决呢?
    楼主,现在解决了吗?
      

  39.   

    我也遇到过这样的问题,但是只是在本地机器上会出现内存溢出情况,
    如果把应用程序部署到服务器上,由于服务器性能原因,基本上能够满
    足客户需求,暂时没出现过内存溢出现象,所以我建议你去服务器上试试(
    开大JVM内存也可以试试,悄悄的,不给他说,哈哈)。
    如果实在不行,我就建议使用cvs下载了(客户不会不同意吧,这类后缀
    名的文件,基本上默认就是用excel方式打开的,基本上不会有什么影响吧)
      

  40.   

    我也遇到过这样的问题,但是只是在本地机器上会出现内存溢出情况,
    如果把应用程序部署到服务器上,由于服务器性能原因,基本上能够满
    足客户需求,暂时没出现过内存溢出现象,所以我建议你去服务器上试试(
    开大JVM内存也可以试试,悄悄的,不给他说,哈哈)。
    如果实在不行,我就建议使用cvs下载了(客户不会不同意吧,这类后缀
    名的文件,基本上默认就是用excel方式打开的,基本上不会有什么影响吧)
      

  41.   

    你们怎么能讨论到一半就不讨论了捏?怎么解决啊,亲,我也遇到这问题了分文件可以,合并的时候还是爆掉了。。我用的JXL。
      

  42.   

    03的話,用eventusermodel模式
    07的話,用流輸出模式
      

  43.   

    参考 java向excel导出海量数据
      

  44.   

    恩,我也遇到了,不过想了个笨方法,能向一个Excel文件的每个sheet页签写100W数据,普通电脑完全没有问题.
    我用的是POI.采用POI的SXSSFWorkbook对象,如:
    SXSSFWorkbook workbook = new SXSSFWorkbook(100);这个100就是缓存行数,就这样往Excel写,写个100万不是问题,速度也很快.如果是需要向一个现有的Excel文件再次写入数据,并且现有的Excel文件已经有很多数据了,如100万.
    则直接向该文件写入还是会溢出,最好是每次都新写个Excel文件,然后再调用VB,执行2个Excel文件之间的sheet拷贝,这样是可以成功的
      

  45.   

    今天也遇到这个问题了
    看完个位的回复很有心得,最后想到每写完一行数据就从list中移除这条数据。
    这样就解决了内存不足的情况,大家可以试试~~