zoukankan      html  css  js  c++  java
  • 有效提升大数据量写入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
  • 相关阅读:
    2017中国大学生程序设计竞赛
    [POJ3667]Hotel(线段树,区间合并,重写)
    [HDOJ3308]LCIS(线段树,区间合并,新的代码)
    [HDOJ5091]Beam Cannon(贪心,线段树,扫描线,矩形内覆盖最多点)
    HDU 5128.The E-pang Palace-计算几何
    HDU 5127.Dogs' Candies-STL(vector)神奇的题,set过不了 (2014ACM/ICPC亚洲区广州站-重现赛(感谢华工和北大))
    洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
    hihoCoder #1831 : 80 Days-RMQ (ACM/ICPC 2018亚洲区预选赛北京赛站网络赛)
    ACM竞赛常用头文件模板-备忘
    C++-二维vector初始化大小方法-备忘
  • 原文地址:https://www.cnblogs.com/xiaosiyuan/p/8995126.html
Copyright © 2011-2022 走看看