package com.walker.di.excel; import com.alibaba.excel.context.AnalysisContext; import com.walker.di.BusinessImportException; import com.walker.infrastructure.ApplicationRuntimeException; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 支持批量加载导入的监听器实现。 * @author 时克英 * @date 2023-02-03 */ public class BatchDataListener extends DefaultDataListener{ // 处理数据计数器 private long currentDataRowCount = 0; private long saveSizeOnce = 200; private long sleepMillSeconds = 0; public BatchDataListener(LoadListener loadListener) { super(loadListener); if(loadListener == null){ throw new IllegalArgumentException("LoadListener is required!"); } } @Override public void invoke(Map integerStringMap, AnalysisContext analysisContext) { // logger.debug(integerStringMap.toString()); this.increaseOneData(integerStringMap); this.currentDataRowCount ++; // 到达200条后,自动保存 if(this.currentDataRowCount >= this.saveSizeOnce){ // try { // this.loadListener.onSave(rows, this.headers); // this.rows.clear(); // this.rows = null; // } catch (DataImportException e) { // throw new ApplicationRuntimeException("loadListener保存导入数据错误:" + e.getMessage(), e); // } this.doSaveOnce(); // 复位行计数器 this.currentDataRowCount = 0; if(sleepMillSeconds > 0){ try { TimeUnit.MILLISECONDS.sleep(sleepMillSeconds); logger.debug("-----> sleep: " + sleepMillSeconds); } catch (InterruptedException e) { logger.error("间隔等待(防止CUP过高),出现异常:" + e.getMessage()); } } } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { logger.info(".........Excel操作完成!"); if(this.rows != null){ logger.warn("excel已加载完毕,发现存在未保存数据,立即保存:" + this.rows.size()); this.doSaveOnce(); } if(this.headers != null){ this.headers.clear(); } } private void doSaveOnce(){ try { this.loadListener.onSave(rows, this.headers); this.rows.clear(); this.rows = null; } catch (BusinessImportException e) { // 2023-02-06 如果业务保存数据出错,中断操作,同时刷新并关闭错误记录器,确保能记录之前的校验错误内容。 if(this.loadListener.getErrorWriter() != null){ this.loadListener.getErrorWriter().close(); } throw new ApplicationRuntimeException("loadListener保存导入数据错误:" + e.getMessage(), e); // logger.error("loadListener保存导入数据错误, 继续执行完,防止 errorWrite中断写入。 error:" + e.getMessage(), e); } } /** * 设置每次保存记录数量,这是数据库写入数量。 * @param saveSizeOnce */ public void setSaveSizeOnce(long saveSizeOnce) { this.saveSizeOnce = saveSizeOnce; } public void setSleepMillSeconds(long sleepMillSeconds) { this.sleepMillSeconds = sleepMillSeconds; } }