在导入需求中,往往要求用户输入值的合法性,如是否为空的校验、正则校验、存在性校验,在以往实现方案中,通常是使用for循环来实现的,但是在Excel工具解析文件的过程中,其实已经逐行解析数据过一遍,如果在业务逻辑中再次for循环读取一次,实则是没有必要的,因此,我们可以使用Easy Excel提供AnalysisEventListener监听器实现。
举个导入的例子,导入若干条用户信息,包括姓名、手机号、性别等信息,其中姓名、手机号不能为空,并抛出某行错误原因。
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class UserImportExample {
public static void main(String[] args) {
String filePath = "path/to/user_data.xlsx";
List<UserInfo> userList = new ArrayList<>();
// 创建监听器
AnalysisEventListener<UserInfo> listener = new AnalysisEventListener<UserInfo>() {
private boolean hasError = false; // 是否存在错误
private int errorRowNum = -1; // 错误行号
private String errorMessage = ""; // 错误信息
@Override
public void invoke(UserInfo userInfo, AnalysisContext analysisContext) {
int currentRowNum = analysisContext.readRowHolder().getRowIndex() + 1; // 获取当前行号(从1开始)
// 对姓名和手机号进行非空校验
if (StringUtils.isEmpty(userInfo.getName()) || StringUtils.isEmpty(userInfo.getPhone())) {
hasError = true;
errorRowNum = currentRowNum;
errorMessage = "姓名和手机号不能为空";
// 抛出异常或进行其他处理
throw new RuntimeException("第" + errorRowNum + "行出现错误:" + errorMessage);
} else {
// 添加非空的用户信息到列表中
userList.add(userInfo);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 数据读取完毕后的处理,可在这里做一些收尾工作
if (!hasError) {
// 所有数据校验通过,继续后续操作
}
}
};
try {
// 执行导入操作
EasyExcel.read(filePath, UserInfo.class, listener).sheet().doRead();
} catch (Exception e) {
// 捕获异常,获取具体某一行的错误原因
if (e instanceof RuntimeException) {
System.out.println(e.getMessage());
} else {
// 处理其他异常
e.printStackTrace();
}
}
// 打印导入的用户信息
for (UserInfo user : userList) {
System.out.println("姓名:" + user.getName() + ",手机号:" + user.getPhone() + ",性别:" + user.getGender());
}
}
}
EasyExcel 的监听器(Listener)实现原理是基于事件驱动的设计模式。在读取或写入 Excel 数据时,EasyExcel 会触发不同的事件,并通过监听器来处理这些事件。
对于读取操作,EasyExcel 使用 SAX(Simple API for XML)解析器进行数据的逐行读取。在解析过程中,当 SAX 解析器读取到每个单元格数据时,EasyExcel 会触发相应的事件,并将读取到的数据传递给监听器进行处理。这些事件包括开始解析、读取到行数据、读取到单元格数据等。监听器通过实现 AnalysisEventListener
接口,并重写其中的方法来处理这些事件。
对于写入操作,EasyExcel 使用 Apache POI 库进行数据的写入。在写入数据时,EasyExcel 会调用监听器的相应方法,如 cellWrite
、afterCellCreate
等,以便监听器可以在写入每个单元格时进行自定义操作。
通过监听器,您可以在读取或写入过程中的不同阶段进行逻辑处理、数据校验、数据转换等操作。监听器使您能够以事件驱动的方式对 Excel 数据进行处理,从而更好地控制和定制您的业务逻辑。