欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java向excel 写入海量数据内存溢出问题 解决

程序员文章站 2022-07-05 21:23:55
由于项目中有导出海量数据的需求,在谷歌和百度也没有找到好的解决办法,经过仔细研究发现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...

由于项目中有导出海量数据的需求,在谷歌和百度也没有找到好的解决办法,经过仔细研究发现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;

/**
 * @description:TestA
 * @author     :liuf 
 * @since      :2020/11/11 9:57
 */
public class TestA {

    /*** @param args*/
    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 disk
        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:/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之后,输出明显减慢,

很快输出如下异常:

5028850289502905029150292 Exception in thread “main”
        java.lang.reflect.InvocationTargetException 
        at 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

本文地址:https://blog.csdn.net/weixin_44259233/article/details/109613425

相关标签: excel poi java