阿里巴巴 Easyexcel 导入 (2.6 导入时读取标题数据)

0.基础信息(需要导入的excel表格数据,接收类)

详见2.1文章阿里巴巴 Easyexcel 导入单张sheet (2.1指定字段对应表格列名)

1.ReadListener

package com.example.support.excel.listener;import cn.hutool.json.JSON;import cn.hutool.json.JSONUtil;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.metadata.data.ReadCellData;import com.alibaba.excel.read.listener.ReadListener;import com.alibaba.excel.util.ConverterUtils;import com.example.global.HttpHolder;import com.example.service.ExcelService;import com.example.support.entity.ExcelReadDTO;import lombok.Getter;import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;import java.util.List;import java.util.Map;/** * @author LWB * @Description excel读取的监听器 * 有个很重要的点 ExcelReadListener监听器 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 * 所以,如果需要传入spring管理的对象,要么按照文档中的说明,直接使用构造器传参进来,要么使用ThreadLocal线程级别的变量工具传参 * 实际应用中,可能会需要传入很多的spring管理的对象,或者其他上下文参数,遇到这种情况,建议使用ThreadLocal来传递参数,简单,便捷,无需重复修改构造器 * 如果是简单的传递个别上下文参数,也可以选用构造器传参的方式 */@Slf4jpublic class ExcelReadHeadListener implements ReadListener<ExcelReadDTO> {    private ExcelService excelService;    /**     * 不适用构造器传入,使用threadLocal工具传入     * 适用于读取监听器中,需要使用多个上下文参数的情况     */    public ExcelReadHeadListener(){        this.excelService = HttpHolder.get("excelService",ExcelService.class);        String p1 = HttpHolder.get("p1", String.class);        String p2 = HttpHolder.get("p2", String.class);    }    /**     * 构造器中传入spring管理的对象     * 适用于传入较少上下文参数的情况     * @param excelService     */    public ExcelReadHeadListener(ExcelService excelService){        this.excelService = excelService;    }    /**     * 每隔N条存储数据库,实际使用中可以1000条或者更多,然后清理cachedDataList ,方便内存回收     * 如果表格数据量很大,成千上万条,可以分批进行入库,数量不多的话,没必要做分配     */    private static final int BATCH_COUNT = 100;    /**     * 缓存的数据     */    private List<ExcelReadDTO> cachedDataList = new ArrayList<>(BATCH_COUNT);    /** 终止读取,提示前端的信息 */    @Getter    private String stopMsg;    @Override    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {        //headMap:行索引为key ReadCellData对象为val        log.info("解析到一条Map<Integer, ReadCellData<?>>类型头数据:{}", JSONUtil.toJsonStr(headMap));        //如果想转成成 Map<Integer,String>,有2种方案: key为列索引,val为标题单元格的string        // 方案1: 不要implements ReadListener 而是 extends AnalysisEventListener        // 方案2: 调用 ConverterUtils.convertToStringMap(headMap, context) 自动会转换        //本例使用方案2        log.info("解析到一条Map<Integer,String>类型头数据:{}", JSONUtil.toJsonStr(ConverterUtils.convertToStringMap(headMap, context)));    }    /**     * 这个方法,每一条数据解析都会来调用     * @param data     * @param context     */    @Override    public void invoke(ExcelReadDTO data, AnalysisContext context) {        log.info("正在读取sheet:[{}]的数据:{}",context.readSheetHolder().getSheetName(), data.toString());        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM       /* if (cachedDataList.size() >= BATCH_COUNT) {            //保存            excelService.saveData();            // 存储完成清理 list            cachedDataList.clear();        }*/    }    /**     * 所有数据解析完成了 会来调用     * @param context     */    @Override    public void doAfterAllAnalysed(AnalysisContext context) {        log.info("sheet:[{}]读取完成!",context.readSheetHolder().getSheetName());        //若进行分批处理,在读取完成后,还要检查下 cachedDataList 中是否还有剩余未入库的数据,因为如果没达到缓存最大值,invoke方法不会进行存储        //if(cachedDataList.size() > 0) excelService.saveData();    }}

2 .接口方法

/**     * 读取excel的表头数据     * @param excelFile     * @return     */    @PostMapping("readHead")    @SneakyThrows    public Ret readHead(MultipartFile excelFile){        ExcelReadHeadListener excelReadListener = new ExcelReadHeadListener(excelService);        EasyExcel.read(excelFile.getInputStream(), ExcelReadDTO.class,excelReadListener)                .sheet()//指定读取哪个sheet                .headRowNumber(2)//指定标题行(需要)                .doRead();//执行读取        return Ret.success();    }

3.控制台输出

c.e.s.e.listener.ExcelReadHeadListener   : 解析到一条Map<Integer, ReadCellData<?>>类型头数据:{"0":{"type":"STRING","stringValue":"字符串","rowIndex":0,"columnIndex":0},"1":{"type":"STRING","stringValue":"日期","rowIndex":0,"columnIndex":1},"2":{"type":"STRING","stringValue":"小数","rowIndex":0,"columnIndex":2}}c.e.s.e.listener.ExcelReadHeadListener   : 解析到一条Map<Integer,String>类型头数据:{"0":"字符串","1":"日期","2":"小数"}c.e.s.e.listener.ExcelReadHeadListener   : 解析到一条Map<Integer, ReadCellData<?>>类型头数据:{"0":{"type":"STRING","stringValue":"F1","rowIndex":1,"columnIndex":0},"1":{"type":"STRING","stringValue":"F2","rowIndex":1,"columnIndex":1},"2":{"type":"STRING","stringValue":"F3","rowIndex":1,"columnIndex":2}}c.e.s.e.listener.ExcelReadHeadListener   : 解析到一条Map<Integer,String>类型头数据:{"0":"F1","1":"F2","2":"F3"}c.e.s.e.listener.ExcelReadHeadListener   : 正在读取sheet:[Sheet1]的数据:ExcelReadDTO(str=33020220220514123x, time=Fri May 13 12:34:56 CST 2022, money=1.23)c.e.s.e.listener.ExcelReadHeadListener   : 正在读取sheet:[Sheet1]的数据:ExcelReadDTO(str=330202202205141235, time=Fri May 13 13:34:56 CST 2022, money=1.24)c.e.s.e.listener.ExcelReadHeadListener   : 正在读取sheet:[Sheet1]的数据:ExcelReadDTO(str=330202202205141234, time=Fri May 13 14:34:56 CST 2022, money=1.25)c.e.s.e.listener.ExcelReadHeadListener   : 正在读取sheet:[Sheet1]的数据:ExcelReadDTO(str=330202202205141235, time=Fri May 13 15:34:56 CST 2022, money=1.26)c.e.s.e.listener.ExcelReadHeadListener   : sheet:[Sheet1]读取完成!

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年4月3日
下一篇 2022年4月3日

相关推荐