有效提升大数据量写入excel的效率

在开发过程中经常会有需要将数据导出到 excel 的需求,当数据量很大,达到几万甚至几十万、几百万级别的时候,如何加快生成 excel 的速度呢?
首先普及一下知识背景:
Excel2003 及以下版本一张表最多支持 65536 行、256 列数据,所以要生成十万、百万级别数据就不能用 Excel2003 了;
Excel2007 版本一张表最多支持1048576行,16384 列,基本可以满足百万级别以下的数据量级。

一般通过 poi 生成 excel 的方式如下:(原谅我以前没有研究过poi,就只会用这种方式,而且网上的demo好多也是这种方式)

 1 public static void exportDataToExcel1(String[] header, List<String[]> datas, String path) {
 2         File file = new File(path);
 3         Workbook workbook = null;
 4         if (path.endsWith(EXCEL_2003)) {
 5             workbook = new HSSFWorkbook();
 6         }
 7         if (path.endsWith(EXCEL_2007)) {
 8             workbook = new XSSFWorkbook();
 9         }
10         Sheet sheet = workbook.createSheet();
11         Row firstRow = sheet.createRow(0); //第一行
12         for (int i = 0; i < header.length; i++) {
13             Cell cell = firstRow.createCell(i);
14             cell.setCellValue(header[i]);
15         }
16         if (datas != null && datas.size() > 0) {
17             for (int i = 0; i < datas.size(); i++) {
18                 Row row = sheet.createRow(i + 1);
19                 String[] d = datas.get(i);
20                 for (int j = 0; j < d.length; j++) {
21                     Cell cell = row.createCell(j);
22                     cell.setCellValue(d[j]);
23                 }
24             }
25         }
26         try {
27             OutputStream outputStream = new FileOutputStream(file);
28             workbook.write(outputStream);
29             outputStream.flush();
30             outputStream.close();
31         } catch (FileNotFoundException e) {
32             e.printStackTrace();
33         } catch (IOException e) {
34             e.printStackTrace();
35         }
36     }

利用上述方式生成一张 10万 行、30 列的 excel 表在我的电脑上耗时大约40多秒

数据准备了 1731 ms
导出花费了 46795 ms

查看 poi 官网http://poi.apache.org/spreadsheet/index.html发现从 3.8 beta3 版本开始新增 SXSSF api 用于解决大数据量场景

这种方式新增了自动刷入数据的机制,可以设置一个数据量阈值,达到这个阈值后会将数据刷入到磁盘,缓解了运行时的压力。

改后的代码如下:

public static void exportDataToExcel(String[] header, List<String[]> datas, String path) {
        File file = new File(path);
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(100);
        Sheet sheet = sxssfWorkbook.createSheet();
        Row firstRow = sheet.createRow(0);         //第一行
        for (int i = 0; i < header.length; i++) {
            Cell cell = firstRow.createCell(i);
            cell.setCellValue(header[i]);
        }
        if (datas != null && datas.size() > 0) {
            for (int i = 0; i < datas.size(); i++) {
                Row row = sheet.createRow(i + 1);
                String[] d = datas.get(i);
                for (int j = 0; j < d.length; j++) {
                    Cell cell = row.createCell(j);
                    cell.setCellValue(d[j]);
                }
            }
        }
        try {
            OutputStream outputStream = new FileOutputStream(file);
            sxssfWorkbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            sxssfWorkbook.dispose();
        }
    }

使用这种方式测试相同量级的数据,导出excel缩短到了6、7秒,可见这个提升幅度还是很明显的。

数据准备了 1096 ms
导出花费了 6784 ms

 

posted @ 2018-05-05 16:38  浅夏丶未央  阅读(3081)  评论(0编辑  收藏