封装读excel监听器:不创建对象的读

封装读excel监听器:主打不创建对象的读
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

 

/**
 * 封装读excel监听器:主打不创建对象的读
 *
 * @author wzh
 * @description 继承AnalysisEventListener<Map < Integer, String>>
 * @date 2021/4/20 13:30
 **/
public class CustomListener extends AnalysisEventListener<Map<Integer, String>> {

    private final static Logger logger = LoggerFactory.getLogger(CustomListener.class);

    /**
     * 定义每多少条数据进行数据库保存,目前不确定
     */
    private static final int BATCH_COUNT = 1500;

    @Resource
    private final CustomExcelService customExcelService;

    @Resource
    private String fileVersionNo;

    /**
     * 用list集合保存解析到的结果
     */
    private List<Map<Integer, Map<Integer, String>>> list;

    public List<Map<Integer, Map<Integer, String>>> getList() {
        return list;
    }

    public void setList(List<Map<Integer, Map<Integer, String>>> list) {
        this.list = list;
    }


    /**
     * 重构,把传来的值赋给对应的属性
     *
     * @param customExcelService 自定义excel接口类
     */
    public CustomListener(CustomExcelService customExcelService, String fileVersionNo) {
        this.customExcelService = customExcelService;
        this.fileVersionNo = fileVersionNo;
        list = new ArrayList<>();
    }

    /**
     * 重写invokeHeadMap方法,获去表头,如果有需要获取第一行表头就重写这个方法,不需要则不需要重写
     *
     * @param headMap Excel每行解析的数据为Map<Integer, String>类型,Integer是Excel的列索引,String为Excel的单元格值
     * @param context context能获取一些东西,比如context.readRowHolder().getRowIndex()为Excel的行索引,表头的行索引为0,0之后的都解析成数据
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        logger.info("解析到一条头数据:{}, currentRowHolder: {}", headMap.toString(), context.readRowHolder().getRowIndex());
        Map<Integer, Map<Integer, String>> map = new HashMap<>();
        map.put(context.readRowHolder().getRowIndex(), headMap);
        list.add(map);
    }

    /**
     * 重写invoke方法获得除Excel第一行表头之后的数据,
     * 如果Excel第二行也是表头,那么也会解析到这里,如果不需要就通过判断context.readRowHolder().getRowIndex()跳过
     *
     * @param data    除了第一行表头外,数据都会解析到这个方法
     * @param context 和上面解释一样
     */
    @SneakyThrows
    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        logger.info("解析到一条数据:{}, currentRowIndex: {}----", data.toString(), context.readRowHolder().getRowIndex());
        Map<Integer, Map<Integer, String>> map = new HashMap<>();
        map.put(context.readRowHolder().getRowIndex(), data);
        list.add(map);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 解析到最后会进入这个方法,需要重写这个doAfterAllAnalysed方法,然后里面调用自己定义好保存方法
     *
     * @param context 解析上下文
     */
    @SneakyThrows
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        logger.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() throws ParseException {
        logger.info("{}条数据,开始存储数据库!", list.size());
        customExcelService.doSaveForExcel(list, fileVersionNo);
        list.clear();
    }


}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值