Easy Excel参数校验实现

2023-10-11 09:38:52 浏览数 (1)

应用场景

在导入需求中,往往要求用户输入值的合法性,如是否为空的校验、正则校验、存在性校验,在以往实现方案中,通常是使用for循环来实现的,但是在Excel工具解析文件的过程中,其实已经逐行解析数据过一遍,如果在业务逻辑中再次for循环读取一次,实则是没有必要的,因此,我们可以使用Easy Excel提供AnalysisEventListener监听器实现。

Easy Excel通过Listener实现参数合规校验方案

举个导入的例子,导入若干条用户信息,包括姓名、手机号、性别等信息,其中姓名、手机号不能为空,并抛出某行错误原因。

代码语言:javascript复制
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 会调用监听器的相应方法,如 cellWriteafterCellCreate 等,以便监听器可以在写入每个单元格时进行自定义操作。

通过监听器,您可以在读取或写入过程中的不同阶段进行逻辑处理、数据校验、数据转换等操作。监听器使您能够以事件驱动的方式对 Excel 数据进行处理,从而更好地控制和定制您的业务逻辑。

0 人点赞