EasyExcel中非常重要的AnalysisEventListener类使用,继承该类并重写invoke、doAfterAllAnalysed,必要时重写onException方法。
Listener 中方法的执行顺序
首先先执行 invokeHeadMap() 读取表头,每一行都读完后,执行 invoke()方法 读取数据,最后是doAfterAllAnalysed() 方法。
invoke通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据。对当前获取的行的数据配合实体类字段的校验注解来实现数据校验,并返回错误提示,也可校验表头(相应index下表对应excel中的中文名称)是否正确。
doAfterAllAnalysed方法可定义在资源解析完成之后的操作 onException方法定义在数据解析出错失败时的操作,一般为当前数据行的数据无法与ExcelProperty所注解的字段类型想符合,从而导致无法继续解析流沉的错误。
一、ExcelListener监听器
public class ExcelListener extends AnalysisEventListener {
/**
* 自定义用于暂时存储data。
* 可以通过实例获取该值
*/
private List<Object> datas = new ArrayList<>();
private List<ImportErrVo> errDatas = new ArrayList<>();
private Map<Integer, String> headMap = new HashMap<>();
private Boolean head = false;
/**
* 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据
*/
@Override
public void invoke(Object object, AnalysisContext context) {
checkHead(object);
//属性验证
int rowNum = context.readRowHolder().getRowIndex();
String errMsg;
try {
errMsg = EasyExcelValiHelper.validateEntity(object);
} catch (Exception e) {
errMsg = "解析数据出错";
e.printStackTrace();
}
if (!StringUtils.isEmpty(errMsg)) {
ImportErrVo errVo = new ImportErrVo();
errVo.setLine(rowNum + 1 + "");
errVo.setErrMsg(errMsg);
errDatas.add(errVo);
} else {
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
datas.add(object);
}
//根据业务自行 dosomething
doSomething();
}
/**
* 根据业务自行实现该方法
*/
private void doSomething() {
}
/**
* 校验表头判断是否传错
*
* @param object
*/
public void checkHead(Object object) {
Field[] fields = object.getClass().getDeclaredFields();
if (head) {
return;
}
for (Field f : fields) {
if (f.getName().equals("serialVersionUID")) {
continue;
}
ExcelProperty excelProperty = f.getAnnotation(ExcelProperty.class);
int index = 0;
if (excelProperty!=null){
index= excelProperty.index();
}
if ((excelProperty != null && headMap.get(index)==null) || (excelProperty != null && !headMap.get(index).equals(excelProperty.value()[excelProperty.value().length-1]))) {
ImportErrVo errVo = new ImportErrVo();
errVo.setLine("1");
errVo.setErrMsg("表头数据不对应,导入数据失败");
errDatas.add(errVo);
this.head = true;
break;
}
}
}
/**
* 解析结束的操作
*
* @param object
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
if (head) {
errDatas.removeIf(a -> !a.getLine().equals("1"));<