栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

EasyExcel解析简易动态表头列及其简用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

EasyExcel解析简易动态表头列及其简用

前言

项目组祖传的POI代码,是基于entity实体类来固定格式解析,对应EXCEL是多少表头展示解析多少表头,需要改祖传代码,比较麻烦,时间不够。故用二次封装POI的EasyExcel来进行简易实现。


使用EasyExcel的优点

是基于POI进行的封装,其特点是:

    占用内存少。3M的excel用POI sax依然需要100M,而easyExcel只是KB级别。简洁。poi代码臃肿,easyExcel只需几行代码。

处理流程
    读取Excel文件输入流:InputStream;将数据输入流映射到自定义的Listenner(重写);Listenner中对每一行数据进行处理(分为表头和表身);解析完毕,获取Listenner中自创建数据结构缓存的数据;

依赖

PS:如果项目中已经存在poi、poi-ooxml、poi-ooxml-schemas版本,起码要3.17以上。



   com.alibaba
   fastjson
   1.2.75




com.alibaba
easyexcel
2.2.6


解析单行表头的Excel

单行表头,不定表头列和数据列。


自定义处理Listenner

自定义Listenner重写核心的三个方法,这个Listenner有点像是流式计算的算子一样:

    invoke:处理每一行数据;invokeHeadMap:处理表头数据;doAfterAllAnalysed:处理完毕的后置操作;
public class ExcelListener extends AnalysisEventListener> {
    //Excel数据缓存结构
    private List>> list;
    //Excel表头(列名)数据缓存结构
    private Map headTitleMap = new HashMap<>();

    public ExcelListener() {
        list = new ArrayList<>();
    }

    
    @Override
    public void invoke(Map data, AnalysisContext context) {
        System.out.println("解析单行数据:" + JSON.toJSONString(data));
        Map> map = new HashMap<>();
        map.put(context.readRowHolder().getRowIndex(), data);
        list.add(map);
    }

    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("所有数据解析完成");
    }

    
    @Override
    public void invokeHeadMap(Map headMap, AnalysisContext context) {
        headTitleMap = headMap;
    }

    public List>> getList() {
        return list;
    }

    public Map getHeadTitleMap() {
        return headTitleMap;
    }

}


处理主类

取出Listener缓存的数据,并将表头和表数据组装为JSON格式数据,这里有一个存储的顺序的问题,见下:

public class ParseDynamicExcelMain {
    public static void main(String[] args) throws FileNotFoundException {

        //初始化本地Excel文件流
        File file = new File("D:\思特奇\开发\湖北移动大屏\dimension.xlsx");
        FileInputStream fis = new FileInputStream(file);

        //使用监听器处理文件流
        ExcelListener parseListener = new ExcelListener();
        EasyExcel.read(fis, parseListener).sheet().doRead();

        //获取Listenner缓存的数据结构
        List>> list = parseListener.getList();
        Map headTitleMap = parseListener.getHeadTitleMap();

        //将表头为key,数据为val组合新的Map,用于转换JSON格式
        List> mapList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map> integerMapMap = list.get(i);
            integerMapMap.forEach((k, l) -> {
                Map map = new linkedHashMap<>();
                l.forEach((y, z) -> {
                    map.put(headTitleMap.get(y), z);
                });
                mapList.add(map);
            });
        }
        System.out.println(mapList);
        System.out.println("=============================");
        System.out.println(JSON.toJSONString(mapList));
    }
}
解析结果

这里我们注意一点:同样的put,hashMap结果无序,linkedHashMap有序:。

解析效果(使用hashMap存储结果):


使用linkedHashMap:


若要处理entity对象

通过处理实体类对象,我们可以指定列的下标或者列名,来获取局部的Excel的列数据。


重写Listenner

将Listenner的传参类型修改为entity对象类型即可,重写invoke,无需重写invokeHeadMap方法。

public class ExcelListener extends AnalysisEventListener {

public void invoke(User user, AnalysisContext context) {

构建实体类对象

index 参数代表excel对应的列; value表示列对应的名称,在写入excel时作用较大;

	
public class User {
    
    @ExcelProperty(index = 0,value = "完成率")
    private String completeRate;
    
    @ExcelProperty(index = 1,value = "数据日期")
    private String dataDate;
    
    @ExcelProperty(index = 2,value = "目标值")
    private String goalVal;
    
    @ExcelProperty(index = 3,value = "完成值")
    private String completeval;
    
    //省略空参和全参构造方法
}

读取多个sheet
			// 读取excel
            ExcelReader excelReader = EasyExcel.read(inputStream, User.class, listener)
                    .build();
            // 读取sheet0
            ReadSheet readSheet = EasyExcel.readSheet(0).build();
            // 将 sheet 写入 Reader
            excelReader.read(readSheet);

写入Excel

比如写入一个User类对象的数据:

 EasyExcel.write(fileName, User.class)
     .sheet("cbry")							// 指定sheet名称
     .doWrite(new User());		//写入数据

单行表头读取解析效果


参考

Alibaba Easy Excel:官网文档永远值得确定。

SpringBoot 整合EasyExcel 获取动态Excel列名 陈彦斌:博主的这个demo存在顺序不一致的问题,文中已修补。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/736167.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号