| package com.zy.asrs.importexcle; | 
|   | 
| import com.alibaba.excel.context.AnalysisContext; | 
| import com.alibaba.excel.event.AnalysisEventListener; | 
| import com.alibaba.fastjson.JSON; | 
| import com.zy.asrs.entity.BasCrnError; | 
| import com.zy.asrs.service.BasCrnErrorService; | 
| import lombok.SneakyThrows; | 
| import lombok.extern.slf4j.Slf4j; | 
|   | 
| import java.util.ArrayList; | 
| import java.util.List; | 
|   | 
| /** | 
|  * @author pang.jiabao | 
|  * @description 导入垛机异常表监听器 | 
|  * @createDate 2024/9/2 9:56 | 
|  */ | 
| @Slf4j | 
| public class ImportCrnErrListener extends AnalysisEventListener<ImportCrnErrDto> { | 
|     /** | 
|      * 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 | 
|      */ | 
|     private static final int BATCH_COUNT = 400; | 
|   | 
|     private int count = 0; | 
|   | 
|     List<ImportCrnErrDto> list = new ArrayList<>(); | 
|     /** | 
|      * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 | 
|      */ | 
|     private final BasCrnErrorService basCrnErrorService; | 
|   | 
|     /** | 
|      * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 | 
|      */ | 
|     public ImportCrnErrListener(BasCrnErrorService basCrnErrorService) { | 
|             this.basCrnErrorService = basCrnErrorService; | 
|     } | 
|   | 
|     /** | 
|      * 这个每一条数据解析都会来调用 | 
|      */ | 
|     @SneakyThrows | 
|     @Override | 
|     public void invoke(ImportCrnErrDto data, AnalysisContext context) { | 
|         log.info("解析到第 {} 条数据:{}", ++count, JSON.toJSONString(data)); | 
|         if (!data.getColumn2().equals("<No value>")) { | 
|             list.add(data); | 
|         } | 
|   | 
|         // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM | 
|         if (list.size() >= BATCH_COUNT) { | 
|             saveData(); | 
|             // 存储完成清理 list | 
|             list.clear(); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 所有数据解析完成了 都会来调用 | 
|      */ | 
|     @Override | 
|     public void doAfterAllAnalysed(AnalysisContext context) { | 
|         // 这里也要保存数据,确保最后遗留的数据也存储到数据库 | 
|         if (list.size() > 0) { | 
|             saveData(); | 
|         } | 
|         log.info("所有数据解析完成!"); | 
|     } | 
|   | 
|     /** | 
|      * 加上存储数据库 | 
|      */ | 
|     private void saveData() { | 
|         log.info("{}条数据,开始存储数据库!", list.size()); | 
|         List<BasCrnError> basCrnErrors = new ArrayList<>(); | 
|         list.forEach(importCrnErrDto -> { | 
|             BasCrnError basCrnError = new BasCrnError(); | 
|             basCrnError.setErrorCode(importCrnErrDto.getColumn1()); | 
|             basCrnError.setErrName(importCrnErrDto.getColumn2()); | 
|             basCrnErrors.add(basCrnError); | 
|         }); | 
|         basCrnErrorService.insertBatch(basCrnErrors); | 
|   | 
|         log.info("存储数据库成功!"); | 
|     } | 
|     /** | 
|      *解析出现错误会进入该方法 具体看源代码或文档 | 
|      */ | 
|     @Override | 
|     public void onException(Exception exception, AnalysisContext context) throws Exception { | 
|         log.error("处理异常:" + exception.getMessage()); | 
|         throw exception; | 
|     } | 
| } |