当前位置 主页 > 服务器问题 > Linux/apache问题 >

    java poi sax方式处理大数据量excel文件

    栏目:Linux/apache问题 时间:2020-01-19 11:30

    系统需要用到一个导入excel文件的功能,使用poi组件常规方式读取excel时,内存耗尽,OutOfMemoryError,或者读取非常慢
    所以写了一个工具类,使用poi sax方式读取excel,速度快很多,内存消耗可以接受。

    测试结果如下:
    .xlsx文件,35M大小,总4个sheel,
    只读取第一个,37434行,54列

    总行数:37434
    读取耗时:39秒
    打印耗时:17秒

    主要代码如下:

    ExcelUtils.class 主入口

    package com.xxx.bi.utils.excel;
    
    import java.util.List;
    import java.util.Objects;
    
    import org.apache.commons.lang3.StringUtils;
    
    import com.google.common.collect.Lists;
    
    public class ExcelUtils {
      /** logger日志. */
      // public static final Logger LOGGER = Logger.getLogger(ExcelUtils.class);
    
      public ExcelUtils() {
      }
    
      /**
       * 获取excel的表头
       * 
       * @param filePath
       *      文件路径
       * @param headerNum
       *      表头所在行数
       * @return
       */
      public static List<String> getHeader(String filePath, int headerNum) {
        if (StringUtils.isBlank(filePath)) {
          throw new IllegalArgumentException("传入文件路径不能为空");
        }
        if (Objects.isNull(headerNum) || headerNum < 1) {
          headerNum = 1;
        }
        try {
          return LargeExcelFileReadUtil.getRowFromSheetOne(filePath, headerNum);
        } catch (Exception e) {
          // LOGGER.info("获取excel[" + filePath + "]表头失败,原因:", e);
          e.printStackTrace();
        }
        return Lists.newArrayList();
      }
    
      /**
       * 获取excel的所有数据<br/>
       * 所有数据类型都是String<br/>
       * 会以第一行数据的列数为总列数,所以第一行的数据必须都不为空,否则可能出java.lang.IndexOutOfBoundsException
       * 
       * @param filePath
       *      文件路径
       * @param headerNum
       *      表头所在行数
       * @return
       */
      public static List<List<String>> getAllData(String filePath) {
        if (StringUtils.isBlank(filePath)) {
          throw new IllegalArgumentException("传入文件路径不能为空");
        }
        try {
          return LargeExcelFileReadUtil.getRowsFromSheetOne(filePath);
        } catch (Exception e) {
          // LOGGER.info("获取excel[" + filePath + "]表头失败,原因:", e);
          e.printStackTrace();
        }
        return Lists.newArrayList();
      }
    
      public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String filepath = "C:/Users/Administrator/Desktop/05-作业调配表 -快递.xlsx";
        // List<String> result = ExcelUtils.getHeader(filepath, 1);
        // for (String col : result) {
        // System.out.println(col);
        // }
    
        List<List<String>> result = ExcelUtils.getAllData(filepath);
        long end = System.currentTimeMillis();
        for (List<String> list : result) {
          System.out.println(list.toString());
        }
        long end1 = System.currentTimeMillis();
        try {
          Thread.sleep(1000l);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.err.println("总行数:" + result.size());
        System.err.println(("读取耗时:" + (end - start) / 1000) + "秒");
        System.err.println(("打印耗时:" + (end1 - end) / 1000) + "秒");
      }
    }