EasyExcel数据校验规则设定及其实现

2025-04发布5次浏览

在使用EasyExcel进行数据导入时,数据校验是确保数据质量和业务逻辑正确的重要步骤。本文将详细介绍如何在EasyExcel中设定数据校验规则,并通过代码示例和流程解析展示其实现过程。

1. EasyExcel简介

EasyExcel 是阿里巴巴开源的一个基于 Java 的 Excel 处理工具,旨在简化 Excel 文件的读写操作。它支持大文件的高效读取,同时提供了灵活的数据校验机制。

2. 数据校验的重要性

在实际项目中,用户上传的 Excel 文件可能包含各种错误数据,如格式不正确、超出范围的数值或非法字符等。如果不加以校验,这些错误数据可能会导致程序崩溃或产生错误结果。因此,在导入数据前进行严格的校验是非常必要的。

3. 数据校验规则设定

3.1 定义实体类

首先需要定义一个与 Excel 表格结构对应的实体类,并为每个字段添加校验注解。常见的校验注解包括 @NotNull, @Min, @Max, @Pattern 等。

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import javax.validation.constraints.*;

public class User {
    @ExcelProperty("用户名")
    @NotBlank(message = "用户名不能为空")
    private String username;

    @ExcelProperty("年龄")
    @Min(value = 18, message = "年龄不能小于18岁")
    @Max(value = 60, message = "年龄不能大于60岁")
    private Integer age;

    @ExcelProperty("邮箱")
    @Email(message = "邮箱格式不正确")
    private String email;

    @ExcelProperty("注册日期")
    @DateTimeFormat("yyyy-MM-dd")
    private Date registerDate;

    // Getters and Setters
}

3.2 自定义校验器

如果内置的校验注解无法满足需求,可以通过实现自定义校验器来扩展功能。例如,检查某个字段是否唯一。

import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.HashSet;
import java.util.Set;

public class UniqueUsernameVerifier implements CellWriteHandler {
    private final Set<String> usernames = new HashSet<>();

    @Override
    public void afterCellDispose(WriteCellData<?> cellData, Sheet sheet, Cell cell) {
        if (cell.getColumnIndex() == 0) { // 假设用户名在第一列
            String username = cell.getStringCellValue();
            if (!usernames.add(username)) {
                throw new RuntimeException("用户名重复: " + username);
            }
        }
    }
}

4. 实现数据校验

4.1 配置监听器

通过实现 AnalysisEventListener 接口,可以捕获每行数据并执行校验逻辑。

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.ArrayList;
import java.util.List;

public class UserDataListener extends AnalysisEventListener<User> {
    private List<User> failedRecords = new ArrayList<>();

    @Override
    public void invoke(User user, AnalysisContext context) {
        try {
            validate(user);
        } catch (Exception e) {
            failedRecords.add(user);
        }
    }

    private void validate(User user) throws Exception {
        if (user.getAge() < 18 || user.getAge() > 60) {
            throw new IllegalArgumentException("年龄不在有效范围内");
        }
        if (!user.getEmail().matches("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}")) {
            throw new IllegalArgumentException("邮箱格式不正确");
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (!failedRecords.isEmpty()) {
            System.out.println("以下记录未通过校验:");
            for (User user : failedRecords) {
                System.out.println(user.toString());
            }
        }
    }
}

4.2 执行数据导入

import com.alibaba.excel.EasyExcel;

public class ExcelImportDemo {
    public static void main(String[] args) {
        String fileName = "users.xlsx";
        EasyExcel.read(fileName, User.class, new UserDataListener()).sheet().doRead();
    }
}

5. 校验流程图

graph TD;
    A[开始] --> B[读取Excel文件];
    B --> C{是否有下一行};
    C --是--> D[解析当前行数据];
    D --> E[应用校验规则];
    E --> F{是否通过校验};
    F --否--> G[记录失败信息];
    F --是--> H[继续处理下一行];
    H --> C;
    C --否--> I[结束并输出校验结果];