EasyExcel导入数据时会将异常数据忽略(例如数据类型不一致)
所以我们需要将其提供捕获异常的方法重写
效果图:(由于length属性为int类型,所以读取出现类型转换异常)
在继承AnalysisEventListener的类中重写invokeHeadMap和onException方法
public class DemoListener extends AnalysisEventListener<DemoVO> {
// 由于easyexcel每次读取只有一条,这里是为了收集到一定数量后批量插入数据库
List<DemoVO> list = new ArrayList<>(ConstantUtils.LIST_COUNT);
// 由于监听器只能通过new的方式创建,所以可以通过构造器传入dao层对象
private DemoDao demoDao;
// 收集表头和错误数据,利用easyexcel将错误数据返回给用户
private List<List<String>> head = new ArrayList<>();
private List<List<String>> data = new ArrayList<>();
public ShipDataListener(DemoDao demoDao) {
this.demoDao= demoDao;
}
public List<List<String>> getHead() {
return this.head;
}
public List<List<String>> getData() {
return this.data;
}
// 如果要收集错误数据,重写表头是必不可少的,因为错误数据中存储的是以列作为键的map集合,并且不会存入为空的数据
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 工具类见下
EasyExcelErrorFixUtil.setExcelErrorHead(headMap, head);
}
@Override
public void invoke(DemoVO demoVO, AnalysisContext analysisContext) {
list.add(demoVO);
if(list.size() >= ConstantUtils.LIST_COUNT) {
saveData();
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
}
// 重写此方法以便于收集错误数据
@Override
public void onException(Exception exception, AnalysisContext context) {
// 调用以下封装的错误数据收集工具
EasyExcelErrorFixUtil.setErrorData(exception, context, data, head.size());
}
public void saveData() {
if(list.size() > 0) {
demoDao.insertAll(list);
}
}
}
封装的工具类
public class EasyExcelErrorFixUtil {
/**
* 收集导入时的错误数据
* @param exception
* @param context 出现异常的内容
* @param data 将错误数据转换格式后赋值给空集合
* @param size title的长度
*/
public static void setErrorData(Exception exception, AnalysisContext context, List<List<String>> data, int size) {
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException convertException = (ExcelDataConvertException) exception;
int row = convertException.getRowIndex();
int column = convertException.getColumnIndex();
Map<Integer, Cell> cellMapResult = context.readRowHolder().getCellMap();
List<String> dataList = new ArrayList<>();
dataList.add(Integer.toString(row));
for (int i = 0; i < size; i ++) {
if(cellMapResult.get(i) == null) {
dataList.add(null);
} else if(column == i) {
dataList.add("{格式错误}--" + cellMapResult.get(i).toString());
} else {
dataList.add(cellMapResult.get(i).toString());
}
}
data.add(dataList);
}
}
/**
* 收集导入时Excel的title
* @param headMap 传入需要处理的title map集合
* @param head 赋值给空集合
*/
public static void setExcelErrorHead(Map<Integer, String> headMap, List<List<String>> head) {
List<String> errorTips = new ArrayList<>();
errorTips.add("错误数据行");
head.add(errorTips);
for(Map.Entry<Integer, String> entry: headMap.entrySet()) {
List<String> errorHead = new ArrayList<>();
errorHead.add(entry.getValue());
head.add(errorHead);
}
}
}