package com.walker.di.excel; import com.alibaba.excel.EasyExcel; import com.walker.di.BatchLoadListener; import com.walker.di.BusinessImportException; import com.walker.di.Constants; import com.walker.di.DataImportException; import com.walker.di.ErrorWriter; import com.walker.di.support.InputStreamDataImportor; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Map; /** * 基于阿里 EasyExcel 实现的数据导入器。 * @author 时克英 * @date 2023-02-03 */ public abstract class ExcelDataImportor extends InputStreamDataImportor { private String batchError = null; private LoadListener loadListener = new InternalLoadListener(); @Override public void setBatchEnabled() { this.setBatchSize(MAX_BATCH_SIZE); } @Override public void setBatchSize(long batchSize) { super.setBatchSize(batchSize); // 2023-02-03 因为该对象用户到: BatchLoadListener,所以创建一个默认的。 this.setBatchLoadListener(new BatchLoadListener() { @Override public List onBatchLoad(Map> columnsByName, String[] fieldNames, int dataSize) { throw new UnsupportedOperationException("不会使用到该对象"); } }); } @Override protected List acquireImportDataList(Object source) throws DataImportException { this.checkSource(source); try { DefaultDataListener dataListener = new DefaultDataListener(null); dataListener.setHeadRowNumber(this.getHeadRowNumber()); EasyExcel.read((InputStream) source, dataListener) .sheet(0).headRowNumber(this.getHeadRowNumber()).doRead(); // 设置表头(这里只返回标识行,如果存在多行表头,只是最后一行表头) this.setFieldNames(dataListener.getHeaders()); return dataListener.getRows(); } catch (Exception ex){ throw new DataImportException("EasyExcel解析异常:" + ex.getMessage(), ex); } finally { this.releaseSource(source); } } @Override protected void acquireImportBatch(BatchLoadListener batchLoadListener, Object source) throws DataImportException { BatchDataListener dataListener = new BatchDataListener(this.loadListener); dataListener.setHeadRowNumber(this.getHeadRowNumber()); dataListener.setSaveSizeOnce(this.getSaveSizeOnce()); dataListener.setSleepMillSeconds(this.getSleepMillSeconds()); try { EasyExcel.read((InputStream) source, dataListener) .sheet(0).headRowNumber(this.getHeadRowNumber()).doRead(); } catch (Exception ex){ throw new DataImportException("EasyExcel批量解析异常:" + ex.getMessage(), ex); } finally { this.releaseSource(source); } } @Override protected ErrorWriter acquireErrorWriter(String id, List fieldNames) { File errorFile = null; OutputStream errorFileStream = null; errorFile = new File(this.getErrorFile()); try { errorFileStream = new BufferedOutputStream(new FileOutputStream(errorFile)); ErrorWriter errorWriter = new ExcelErrorWriter(errorFileStream, fieldNames); if(this.loadListener != null){ this.loadListener.setErrorWriter(errorWriter); } return errorWriter; // return new ExcelErrorWriter(errorFileStream, fieldNames); } catch (FileNotFoundException e) { logger.error("未找到'错误文件':" + errorFile.getAbsolutePath(), e); return null; } } @Override public String getBatchError(){ return this.batchError; } @Override public String getImportFileSuffix(){ return Constants.IMPORT_ERROR_SUFFIX_XLSX; } private class InternalLoadListener implements LoadListener{ @Override public void onSave(List rows, List fieldNames) throws BusinessImportException { try { // 这里必须设置表头 ExcelDataImportor.this.setFieldNames(fieldNames); ExcelDataImportor.this.doExecuteImport(rows, getFieldNames()); } catch (DataImportException e) { batchError = e.getMessage(); if(e instanceof BusinessImportException){ BusinessImportException bex = (BusinessImportException)e; throw bex; } else { throw new BusinessImportException("批量导入监听错误:" + e.getMessage(), e); } } } @Override public void setErrorWriter(ErrorWriter errorWriter) { this.errorWriter = errorWriter; } @Override public ErrorWriter getErrorWriter() { return this.errorWriter; } private ErrorWriter errorWriter = null; } }