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动态复杂表头导出方法

相关推荐
pengzhuofan3 小时前
第10章 Maven
java·maven
百锦再3 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说3 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多4 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring
百锦再4 小时前
对前后端分离与前后端不分离(通常指服务端渲染)的架构进行全方位的对比分析
java·开发语言·python·架构·eclipse·php·maven
DokiDoki之父4 小时前
Spring—注解开发
java·后端·spring
CodeCraft Studio5 小时前
【能源与流程工业案例】KBC借助TeeChart 打造工业级数据可视化平台
java·信息可视化·.net·能源·teechart·工业可视化·工业图表
摇滚侠5 小时前
Spring Boot 3零基础教程,WEB 开发 默认页签图标 Favicon 笔记29
java·spring boot·笔记
YSRM5 小时前
Leetcode+Java+图论+最小生成树&拓扑排序
java·leetcode·图论