博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【poi】解决java导出excel 海量数据内存溢出问题
阅读量:7096 次
发布时间:2019-06-28

本文共 3446 字,大约阅读时间需要 11 分钟。

 

转自百度经验: 那里排版忒恶心,转来这里。

 

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

 

转载地址:http://dcxql.baihongyu.com/

你可能感兴趣的文章
文件管理命令及变量基础
查看>>
MyBatis--01.基础
查看>>
【Java多线程】的学习总结
查看>>
中文自动摘要的基本实现方法
查看>>
linux memcached集群
查看>>
OpenSSL&搭建私人CA
查看>>
MySQL explain
查看>>
初始MyBatis
查看>>
K-Modes算法[聚类算法]
查看>>
if usage
查看>>
理解ASM(四)条带化原理和rebalance
查看>>
linux 批量修改文件名
查看>>
SQLserver 2008同步复制创建后新增表/函数/存储过程(不重新初始化快照)
查看>>
我们一起清除过的浮动
查看>>
python 实现(简单的一个购物商城小程序)
查看>>
bzoj4025 二分图
查看>>
文档加密、解密jar包
查看>>
Java 8 字符串日期排序
查看>>
了解Python
查看>>
Java遇见HTML——JSP篇之JSP基础语法
查看>>