poi解决java导出excel海量数据内存溢出问题详解编程语言

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

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/17062.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论