作者:烧鸡太子爷

简介

在服务端上做过解析Excel的需求的朋友都知道,Java解析、生成Excel比较有名的框架有Apache poi、jxl,但是这些框架其实都有一个比较严重的问题就是耗费的内存比较多,poi有提供SAX模式的API可以在一定程度的解决一些内存溢出的问题,但是POI还是存在一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

今天要介绍的这款框架是EasyExcel,是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称

性能

EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)

官网介绍他的3.0.2以上版本在64M内存20秒读取75M(46W行25列)的Excel,极速模式还能更快,但是内存占用会在100M多一点

1.png

包引入

版本说明

截稿前最新的版本是3.0.5,2+ 版本支持 Java7和Java6,+ 版本至少 Java8

  • 不建议跨大版本升级 尤其跨2个大版本
  • 2+ 升级到 3+ 一些不兼容的地方

    • 使用了自定义拦截器去修改样式的会出问题(不会编译报错)
    • 读的时候invoke里面抛出异常,不会再额外封装一层ExcelAnalysisException (不会编译报错)
    • 样式等注解涉及到 boolean or 一些枚举 值的 有变动,新增默认值(会编译报错,注解改就行)
  • 大版本升级后建议相关内容重新测试下

maven 引入

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.0.5</version>
    </dependency>

常用类解析

  • EasyExcel 入口类,用于构建开始各种操作
  • ExcelReaderBuilder ExcelWriterBuilder 构建出一个 ReadWorkbook WriteWorkbook,可以理解成一个excel对象,一个excel只要构建一个
  • ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet对象,可以理解成excel里面的一页,每一页都要构建一个
  • ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据
  • WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据
  • 所有配置都是继承的,Workbook的配置会被Sheet继承,所以在用EasyExcel设置参数的时候,在EasyExcel...sheet()方法之前作用域是整个sheet,之后针对单个sheet

excel操作示例

手上有一份公司信息.xlsx,里面有ID,公司名称,成立时间,涉足行业,官方网站5列信息,那我们就来读取一下这份excel表格好了(涉及到一些信息,请允许我打码)

2.png

先上解析结果3.png

下面贴代码

  • 实现信息基础类

      @Data
      public class CompanyInfoData {
          //设置表头名称
          @ExcelProperty("ID")
          private String id;
    
          //设置表头名称
          @ExcelProperty("公司名称")
          private String company_name;
    
          //设置表头名称
          @ExcelProperty("成立时间")
          private String create_time;
    
          //设置表头名称
          @ExcelProperty("涉足行业")
          private String in_industry;
    
          //设置表头名称
          @ExcelProperty("官方网站")
          private String official_website;
      }
  • 创建监听类

      public class ExcelListener extends AnalysisEventListener<CompanyInfoData{
          //创建list集合封装最终的数据
          List<CompanyInfoDatalist = new ArrayList<CompanyInfoData>();
    
          //一行一行去读取excle内容
          @Override
          public void invoke(CompanyInfoData info, AnalysisContext analysisContext) {
              System.out.println("表内容"+info);
              list.add(info);
          }
    
          //读取excel表头信息
          @Override
          public void invokeHeadMap(Map<Integer, StringheadMap, AnalysisContext context) {
              System.out.println("表头信息:"+headMap);
          }
    
          //读取完成后执行
          @Override
          public void doAfterAllAnalysed(AnalysisContext analysisContext) {
          }
      }   
  • 读取文件实现 public class TestEasyExcel {

      public static void main(String[] args) {
    
              String fileName = "E:\\workspace\\flywaydemo\\src\\main\\resources\\公司信息.xlsx";
              // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
              EasyExcel.read(fileName, CompanyInfoData.class, new ExcelListener()).sheet().doRead();
          }
      }

总结

easyexcel对内存的优化相较于其他excel操作框架有一定优势,除了可以对excel进行普通读写以外,他对excel的web上传下载的支持都比较友好,有需要的同学可以去官网详细了解,官网地址:https://www.yuque.com/easyexc...


恒生LIGHT云社区
46 声望7 粉丝

LIGHT云是恒生公司旗下云服务品牌,聚焦金融行业生态圈,依托恒生公司24年技术创新及研发积累,不断探索金融行业各场景的落地和应用,提供一站式云计算行业解决方案。