EasyExcel 校验后导入
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.my.test.eo.listen.ErrMsgEO;
import lombok.extern.slf4j.Slf4j;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public abstract class MyReadListener<T> implements ReadListener<T> {
/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 5;
/**
* 缓存的数据
*/
private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
* 获取要提交的缓存数据
*/
public List<T> getCachedDataList() {
return cachedDataList;
}
/**
* 记录错误信息的list
*/
private List<ErrMsgEO> errList = new ArrayList<>();
/**
* 传入的校验对象
*/
private Validator validator;
/**
* 结束语,统计导入成功失败的条数
*/
private String resultMsg;
public List<ErrMsgEO> getErrList() {
return errList;
}
public void addErr(ErrMsgEO errMsgEO){
getErrList().add(errMsgEO);
}
public String getResultMsg() {
return resultMsg;
}
private void setResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
}
private Validator getValidator() {
return validator;
}
public void setValidator(Validator validator) {
this.validator = validator;
}
/**
* 数据对象加入批量提交缓存list
*/
public void addData(T data){
cachedDataList.add(data);
}
/**
* 校验一个数据对象,有错误就返回错误信息对象
*/
public ErrMsgEO validOne(T data, AnalysisContext context){
R valid = MyValidatorUtils.valid(getValidator(), data);
if (null!=valid) {
ErrMsgEO eo= new ErrMsgEO();
eo.setErr(valid.getMsg());
eo.setRowNum(context.readRowHolder().getRowIndex().toString());
return eo;
}else {
return null;
}
}
/**
* 保存业务逻辑 子类实现
*/
public abstract boolean saveData(AnalysisContext context);
/**
* 业务逻辑的校验
*/
public abstract ErrMsgEO bizValid(T data);
/**
* 判断最后的数据是否能保存
*/
public boolean lastCanSave(){
return getCachedDataList().size() >0;
}
/**
* 校验对象数据, 错误就加入错误信息list,正确就加入缓存数据池
*/
public void validThenAdd(T data, AnalysisContext context){
ErrMsgEO valid = validOne(data, context);
if (null!=valid) {
addErr(valid);
}else {
ErrMsgEO eo = bizValid(data);
if (null!=eo){
addErr(eo);
}else {
addData(data);
}
}
}
/**
*达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
*/
public void tryThenSave(AnalysisContext context){
if (cachedDataList.size() >= BATCH_COUNT) {
// 批量保存
if (saveData(context)) {
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
}
/**
* 校验然后保存
*/
public void validThenSave(T data, AnalysisContext context) {
validThenAdd(data, context);
tryThenSave(context);
}
/**
* 填充导入结果提示
*/
public void fillResultMsg(AnalysisContext context){
int errNum=getErrList().size();
int okNum=context.readSheetHolder().getApproximateTotalRowNumber()-errNum-context.readSheetHolder().getHeadRowNumber();
setResultMsg("成功导入:"+okNum+"条数据,失败:"+errNum+"条数据");
}
public void lastSave(AnalysisContext context){
if (lastCanSave()) {
saveData(context);
}else {
log.info("木有保存");
}
fillResultMsg(context);
}
}