EasyExcel复杂表头数据导入

目录

表头示例

导入代码

java 复制代码
    @Override
    public void importExcel(InputStream inputStream) {
        ItemExcelListener itemExcelListener = new ItemExcelListener();
        EasyExcel.read(inputStream, ImportItem.class, itemExcelListener).headRowNumber(2).sheet().doRead();
    }
java 复制代码
@Slf4j
public class ItemExcelListener extends AnalysisEventListener<ImportItem> {
    /**
     * 定义100条数据存储一次,然后清理list,方便内存回收
     */
    private static final int BATCH_COUNT = 300;
    /**
     * 记录导入的总记录数
     */
    private Long listSize = 0L;
    /**
     * 缓存的数据
     */
    private List<ImportItem> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    //标记处理第一行表头
    private boolean firstRowProcessed = true;

    private HashMap<Integer, HashMap<String,String>> dynamicInfoList;

    /**
     * 解析每一行表头数据时调用
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 读取表头数据并构造HashMap
        if (firstRowProcessed){
            HashMap<Integer, HashMap<String, String>> infoList = new HashMap<>();
            for (Map.Entry<Integer, String> entry : headMap.entrySet()){
                Integer key = entry.getKey();
                String value = entry.getValue();
                if (!Objects.equals(value, "固定数据")){
                    infoList.put(key,null);
                }
            }
            dynamicInfoList = infoList;
            firstRowProcessed = false;
        }else {
            for (Map.Entry<Integer, String> entry : headMap.entrySet()){
                HashMap<String, String> info = new HashMap<>();
                Integer key = entry.getKey();
                String value = entry.getValue();
                if (dynamicInfoList.containsKey(key)){
                    info.put(value,null);
                    dynamicInfoList.replace(key,info);
                }
            }
        }
    }

    /**
     * 每解析一条数据都会调用一次
     */
    @Override
    public void invoke(ImportItem importItem, AnalysisContext analysisContext) {
        // 获取实体类中不匹配的数据
        ReadRowHolder readRowHolder = analysisContext.readRowHolder();
        Map<Integer, Cell> cellMap = readRowHolder.getCellMap();
        JSONObject dynamicInformation = new JSONObject();
        for (Map.Entry<Integer, Cell> entry : cellMap.entrySet()){
            Integer key = entry.getKey();
            Cell entryValue = entry.getValue();
            if (dynamicInfoList.containsKey(key)){
                String string = JSON.toJSONString(entryValue);
                JSONObject jsonObject = JSON.parseObject(string);
                String value = jsonObject.getString("stringValue");
                HashMap<String, String> info = dynamicInfoList.get(key);
                for (String attribute : info.keySet()) {
                    dynamicInformation.put(attribute,value);
                }
            }
        }
        cachedDataList.add(importItem);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成后调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (!cachedDataList.isEmpty()){
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    public void saveData(){
        //将数据存入数据库
    }


}

数据导出

参考文章:EasyExcel动态复杂表头导出方法

相关推荐
微尘寒风6 小时前
【Git】的安装和使用
java·git
y = xⁿ7 小时前
DeepSeek Harness 学习日记:关于Agent接口,工具调用的底层实现
android·java·学习
侧耳倾听1118 小时前
jwt使用简介
java·jwt
顶点多余8 小时前
那些在算法中适合巩固的知识点---1
java·前端·算法
AI人工智能+电脑小能手8 小时前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
jay神8 小时前
【计算机毕业设计】基于SpringBoot的程序教学辅助系统
java·前端·vue.js·spring boot·后端·毕业设计·课程设计
2601_962066499 小时前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
yaoxin52112310 小时前
507. Java 反射 - 在 BeanFactory 中实现依赖注入
java·开发语言
OPEN-F10 小时前
C++模板教程:变参模板、折叠表达式与SFINAE
java·开发语言·c++
2601_9620722111 小时前
SpringMVC进阶(自定义拦截器以及异常处理)
java