JAVA将百万级数据高效的导出到EXCEL表单

遇到的问题

1.list集合太大,触发oom

2.导出excel数据量太大内存占满,没输出到硬盘前已经出发oom

接下来尝试用poi解决

<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>3.10-FINAL</version>
</dependency>
<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml-schemas</artifactId>
     <version>3.10-FINAL</version>
</dependency>

一开始用XSSFWorkbook

rows参数是传进来的总条数,col是输出的总列数

public static void XSSFWorkbook(int rows, int col) throws Exception {
        long start = System.currentTimeMillis();
        XSSFWorkbook workbook1 = new XSSFWorkbook();
        Sheet first = workbook1.createSheet("sheet1");
        for (int i = 0; i < rows; i++) {
            Row row = first.createRow(i);
            for (int j = 0; j < col; j++) {
                if(i == 0) {
                    // 首行
                    row.createCell(j).setCellValue("column" + j);
                } else {
                    // 数据
                    if (j == 0) {
                        CellUtil.createCell(row, j, String.valueOf(i));
                    } else
                        CellUtil.createCell(row, j, String.valueOf(Math.random()));
                }
            }
        }
        FileOutputStream out = new FileOutputStream("E:/XSSFWorkbookworkbook.xlsx");
        workbook1.write(out);
        out.close();
        System.out.println(("XSSFWorkbook "+(System.currentTimeMillis()-start)/1000));
    }

导致触发GC

原因是excel文档的数据都存在内存中,当一直望excel填充数据,那么就越大,内存就扛不住

去poi官网看到

再次回到POI的官网。http://poi.apache.org/spreadsheet/index.html

官方提到自POI3.8版本开始提供了一种SXSSF的方式,用于超大数据量的操作。于是…

原文:

SXSSF is an API-compatible streaming extension of XSSF to be used when very large spreadsheets have to be produced…

 POI类库实现了相对高效的批量写入类SXSSFWorkbook

于是尝试了

public static void SXSSFWorkbook(int rows, int col) throws Exception {
        long start = System.currentTimeMillis();
        XSSFWorkbook workbook1 = new XSSFWorkbook();
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook1, 100);
        Sheet first = sxssfWorkbook.createSheet("sheet1");
        for (int i = 0; i < rows; i++) {
            Row row = first.createRow(i);
            for (int j = 0; j < col; j++) {
                if(i == 0) {
                    // 首行
                    row.createCell(j).setCellValue("column" + j);
                } else {
                    // 数据
                    if (j == 0) {
                        CellUtil.createCell(row, j, String.valueOf(i));
                    } else
                        CellUtil.createCell(row, j, String.valueOf(Math.random()));
                }
            }
        }
        FileOutputStream out = new FileOutputStream("E:/SXSSFWorkbookworkbook.xlsx");
        sxssfWorkbook.write(out);
        out.close();
        System.out.println(("SXSSFWorkbook "+(System.currentTimeMillis()-start)/1000));
    }

看到数据的瞬间感觉,哇塞。好给力的说。居然从将近50秒缩短带11秒。。。

为什么都是代码差距就这么大呢?

原来,SXSSF实现了一套自动刷入数据的机制。当数据数量达到一定程度时(用户可以自己设置这个限制)。像文本中刷入部分数据输出到硬盘中。这样就缓解了程序运行时候内存的压力。达到高效的目的。

原理:用硬盘换内存

当然也有现成的工具类hutool的BigExcelWriter

查看源码只是在poi的基础上封装了一层 

猜你喜欢

转载自blog.csdn.net/qq_38623939/article/details/128845635