easyexcel 2.2.5 以列表的形式读取 Excel

原创 HuangLongPu     发表于  2020-12-14 17:12       417

EasyExcel 为阿里巴巴针对 Excel 文档处理得开源项目,主要为封装简化 Poi 操作,提高内存处理效率等。项目开源的github 地址为:https://github.com/alibaba/easyexcel,针对 EasyExcel 的官方介绍是这么描述的:

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。

针对 Excel 处理,Obatis开源项目的组件库 obatis-office 也是为封装简化 Poi 操作,操作也很简便,开发者可以参考作比较。obatis-office 开源项目地址:https://github.com/obatis/obatis-office,更多建议,也可以提出 issues。

步骤流程:

注:讲述使用 EasyExcel 的读取 Excel 数据列表的案例,项目基于 springboot + maven 模式。

1、引入 EasyExcel 依赖包,文章以 easyexcel 2.2.5 为基础,更多版本,请移步至 EasyExcel maven 中央仓库

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

2、创建 Excel 内容处理转换类 StringArrayExcelReadListener,该类须是 AnalysisEventListener 的子类,并重写 invoke、invokeHeadMap 等方法。

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * StringList 解析监听器
 * @author HaungLongPu
 * @since 2020-12-11
 */
@Slf4j
public class StringArrayExcelReadListener extends AnalysisEventListener<Map<String, String>> {

    /**
     * 存储读取到的表头
     */
    private List<String> head = new ArrayList<>();
    /**
     * 存储读取到的 Excel 数据
     */
    private List<List<String>> data = new ArrayList<>();

    /**
     * 每解析一行都会回调invoke()方法
     * @param item  读取后的数据对象
     * @param context 内容
     */
    @Override
    public void invoke(Map<String, String> item, AnalysisContext context) {
        if(item != null && !item.isEmpty()) {
            List<String> info = item.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
            data.add(info);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    /**
     * 处理读取到的表头数据
     * @param headMap
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        if(headMap != null && !headMap.isEmpty()) {
            head = headMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
        }
    }

    /**
     * 获取表头数据信息
     * @return
     */
    public List<String> getHead() {
        return this.head;
    }

    /**
     * 获取读取到的 Excel 数据
     * @return
     */
    public List<List<String>> getData() {
        return this.data;
    }
}

3、读取文件流,并读取 Excel 文件信息。

@PostMapping("importExcel")
public void excelImportAdd(@RequestParam("file") MultipartFile file) {
    if (file.isEmpty()) {
	    throw new QuZuException("请选择上传文件");
	}

	InputStream inputStream;
	try {
	    inputStream = file.getInputStream();
	} catch (IOException e) {
	    e.printStackTrace();
		throw new QuZuException("解析文件错误");
	}

	StringArrayExcelReadListener listener = new StringArrayExcelReadListener();
	ExcelReader reader = EasyExcelFactory.read(inputStream, listener).build();

	// 读取Sheet,从第0行开始读取(表示从表头开始读)
	ReadSheet readSheet = EasyExcel.readSheet(0).build();
	reader.read(readSheet);
	reader.finish();

	List<String> head = listener.getHead();
	System.out.println(JSON.toJSONString(head));
	List<List<String>> data = listener.getData();
	System.out.println(JSON.toJSONString(data));
}

结束语

EasyExcel 定位为海量数据读取,本文仅以读取列表的形式讲述,更多项目业务需要可参照官方文档。