zoukankan      html  css  js  c++  java
  • 【poi】解决java导出excel 海量数据内存溢出问题

    转自百度经验:http://jingyan.baidu.com/article/4853e1e5202c331909f72627.html 那里排版忒恶心,转来这里。

    由于项目中有导出海量数据的需求,在谷歌和百度也没有找到好的解决办法,经过仔细研究发现poi-3.8版本以上提供新的模式可以满足这个需求,写在这里希望能对有同样需求的同行们有所帮助。

    以下是测试代码:

    import java.io.FileOutputStream;
    import org.apache.commons.lang.exception.ExceptionUtils;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellReference;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
     
    public class Test {
        public static void main(String[] args) {
            if (args[0].equals("hssf")) {
                hssfTest();
            }
     
            if (args[0].equals("sxssf")) {
                sxssfTest();
            }
        }
     
        public static void sxssfTest() {
     
            Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory,
            // exceeding rows will be
            // flushed to diskSheet sh = wb.createSheet()
            ;
            int rownum = 0;
            try {
                while (true) {
                    Row row = sh.createRow(rownum);
                    for (int cellnum = 0; cellnum < 10; cellnum++) {
                        Cell cell = row.createCell(cellnum);
                        String address = new CellReference(cell).formatAsString();
                        cell.setCellValue(address);
                    }
                    System.out.println(rownum);
                    rownum++;
                    if (rownum >= 1000000)
                        break;
     
                }
                FileOutputStream out = new FileOutputStream("c:/sxssf.xlsx");
                wb.write(out);
                out.close();
            } catch (Exception e) {
                System.out.println(ExceptionUtils.getFullStackTrace(e));
            }
        }
     
        public static void hssfTest() {
            XSSFWorkbook wb = new XSSFWorkbook();
            Sheet sh = wb.createSheet();
            int rownum = 0;
            try {
                while (true) {
                    Row row = sh.createRow(rownum);
                    for (int cellnum = 0; cellnum < 10; cellnum++) {
                        Cell cell = row.createCell(cellnum);
                        String address = new CellReference(cell).formatAsString();
                        cell.setCellValue(address);
                    }
                    System.out.println(rownum);
                    rownum++;
                    if (rownum >= 1000000)
                        break;
                }
                FileOutputStream out = new FileOutputStream("c:/hssf.xlsx");
                wb.write(out);
                out.close();
            } catch (Exception e) {
                System.out.println(ExceptionUtils.getFullStackTrace(e));
            }
        }
    }

    将工程打包成jar到C:,然后用命令行java -jar -Xms128m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=512M test.jar hssf 执行,在命令行窗口输出到45000之后,输出明显减慢,

    很快输出如下异常:

    5028850289502905029150292Exception in thread “main” java.lang.reflect.InvocationTargetExceptionat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:585)at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)Caused by: java.lang.OutOfMemoryError: Java heap space

    继续用命令行java -jar -Xms128m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=512M test.jar sxssf执行,

    命令行窗口输出速度一直保持不变,直到循环完了,并最终生成四十多M的excel—sxssf.xlsx

    总结来说,这段代码,我看了N久才看到楼主的意思。就是说 运行hssf.java就会内存溢出,所以换了个实现方式, 运行sxssf.java就ok了。所以解决方法就是参照sxssf这个类了。

  • 相关阅读:
    BZOJ 1707 [Usaco2007 Nov]tanning分配防晒霜
    BZOJ2697:特技飞行
    Bridging signals(NlogN最长上升子序列)
    HDU 4291 A Short problem(矩阵+循环节)
    计蒜之道 初赛第一场B 阿里天池的新任务(简单)
    1008: [HNOI2008]越狱
    1022: [SHOI2008]小约翰的游戏John
    1192: [HNOI2006]鬼谷子的钱袋
    2456: mode
    BZOJ-1968
  • 原文地址:https://www.cnblogs.com/ae6623/p/4416432.html
Copyright © 2011-2022 走看看