一个excel有多个sheet的时候,每个sheet需要对应一个实体类,一个mapper,一个监听器。监听器代码重复率很高,如何实现抽取公共方法呢。

service

采用循环的方式读取,建两个枚举类,一个是实体类枚举,一个是mapper枚举,

@Slf4j
@Service
public class ExcelFileSystemServiceImpl implements ExcelFileSystemService {
    private static final int NUM_LISTENERS = 8;

    @SneakyThrows
    @Override
    public void uploadFile(MultipartFile file){
        try (ExcelReader excelReader = EasyExcelFactory.read(file.getInputStream()).build()) {
            excelReader.read(listenersAndReadSheets());
        }
    }
    public List<ReadSheet> listenersAndReadSheets() {
        List<ReadSheet> readSheets = new ArrayList<>(NUM_LISTENERS);
        for (int i = 0; i < NUM_LISTENERS; i++) {
            try {
                NoModelDataListener< ?, ? > listener = new NoModelDataListener<>(DaoClassEnum.getDaoClass().get(i));
                ReadSheet readSheet = createReadSheet(i, listener, Class.forName(EntityClassEnum.getEntityClass().get(i)));
                readSheets.add(readSheet);
            } catch (Exception e) {
                // 处理可能的异常,例如日志记录或错误回报
                log.error("Error initializing listener/readSheet for " + EntityClassEnum.getEntityClass().get(i));
                e.printStackTrace();
            }
        }
        return readSheets;
    }
    private ReadSheet createReadSheet(int sheetIndex, NoModelDataListener<?,?> listener, Class<?> entityClass) {
        return EasyExcelFactory.readSheet(sheetIndex)
                .headRowNumber(2)
                .head(entityClass)
                .registerReadListener(listener)
                .build();
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

NoModelDataListener监听器

@Slf4j
public class NoModelDataListener<X extends BaseAreaEntity,Y extends BatchBaseMapper<X>> extends AnalysisEventListener<X> {

    Class<Y> yClass;
    @SuppressWarnings("unchecked")
    public NoModelDataListener(Class<?> yClass) {
        this.yClass = (Class<Y>) yClass;
    }

    /**
     * 每隔10000条存储数据库,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 10000;
    private List<X> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    @Override
    public void invoke(X data, AnalysisContext context) {
        cachedDataList.add(data);
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", cachedDataList.size());
        Y y = SpringContentUtils.getBean(yClass);
        y.insertBatch(cachedDataList,BATCH_COUNT / 100);
        log.info("存储数据库成功!");
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.