# excel校验工具 **Repository Path**: xzjsccz/cc-excel-util ## Basic Information - **Project Name**: excel校验工具 - **Description**: cc-exel-util一个简单Excel导入数据校验工具,支持hibernate注解校验,并支持多属性关联校验和多sheet校验, 并且还支持sheet关联属性校验。只需要添加注解,实现对应的接口即可,不用用户写大量的校验逻辑。 - **Primary Language**: Java - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 12 - **Forks**: 1 - **Created**: 2024-02-05 - **Last Updated**: 2025-09-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: Excel, Java, java-util, Excel工具 ## README # cc-excel-util ## 概述 cc-excel-util 是一个面向 Excel 数据导入的轻量校验与标注工具。支持 Hibernate Validator 注解校验、对象内多属性关联校验、跨 Sheet 关联校验,以及通过服务扩展自定义校验与对象转换。设计目标:用最少的样板代码完成复杂 Excel 校验与错误回写,降低接入成本。 ## 功能特性 - **注解式字段校验**:基于 Hibernate Validator(如 `@NotBlank`),并内置扩展注解 `@InList` - **关联校验**: - 对象内多属性关联:通过 `@RelatedClass` + `ValidatedRelatedFieldService` - 跨 Sheet 关联:通过 `@RelatedSheet` + `ValidatedRelatedSheetService` - **多种导入模式**: - 单 Sheet 校验并错误写回模板/Excel - 多 Sheet 批量校验,支持指定各 Sheet 起始行与输出模板 - 直接返回校验后的数据集合,或生成带错误标注的工作簿流(便于 Web 下载) - **服务注册器**:在非 Spring 环境下,使用 `ServiceRegistry` 完成校验/转换服务注册 - **对象转换**:`ConvertObjectService` 支持成功数据转换 ## 安装与集成 ### 1. 获取依赖 当前仓库未声明公共仓库坐标,推荐方式:本地打包后引入 使用 Maven 打包生成 jar: ```bash mvn clean package -DskipTests ``` 将生成的 jar 引入你的项目(或作为本地模块依赖)。 ### 2. 运行时依赖建议 ```xml org.hibernate.validator hibernate-validator 8.0.1.Final org.glassfish jakarta.el 4.0.2 runtime org.apache.poi poi-ooxml 5.2.5 org.projectlombok lombok 1.18.32 provided ``` ### 3. 初始化(必须) 首次使用前调用: ```java ValidatorUtils.initialize(); ``` ## 快速开始 ### 1. 定义实体与注解 ```java @RelatedClass // 如果需要对象内关联校验 public class Student { @NotBlank(message = "名字不能为空") private String name; private String age; @InList(values = {"一班","二班"}, message = "班级错误") private String studentClass; private String source; // getter/setter... } ``` ### 2. 注册业务校验服务(可选,需关联校验时) ```java public class StudentFieldValidator implements ValidatedRelatedFieldService { @Override public boolean validator(Student s) { // 示例:成绩>=90却未分到"一班" if (s.getSource() != null) { int score = Integer.parseInt(s.getSource()); if (score >= 90 && !"一班".equals(s.getStudentClass())) { return ViolationUtils.addViolation("studentClass", "班级分配错误"); } } return true; } } // 非 Spring 环境,使用注册器注册 ValidatorUtils.initialize(); ServiceRegistry.registerFieldService(new StudentFieldValidator()); ``` ### 3. 读取与校验单 Sheet,并将错误回写到结果文件 ```java List okList = CheckExcelUtil.checkExcelData( "/path/input.xlsx", Student.class, "/path/result.xlsx" ); ``` ### 4. 多 Sheet 校验(返回文件) ```java try (FileInputStream in = new FileInputStream("/path/input.xlsx")) { Map> okData = CheckExcelUtil.checkExcelAllSheet(in, "/path/result.xlsx", Student.class, StudentClass.class); } ``` ### 5. 仅做对象校验(非 Excel) ```java Student s = new Student(); s.setName("zs"); CheckDataUtil.checkData(s); // 失败直接抛出首个错误信息 ``` ## 注解与扩展 ### Bean Validation 标准注解 如 `@NotBlank`, `@NotNull`, `@Size`, 等均可直接使用。 ### 内置扩展注解 - `@InList(values = {"一班","二班"}, message = "班级错误")`:限制字段值在给定集合中 ### 关联注解 - `@RelatedClass`:标记该类存在对象级业务校验;实现 `ValidatedRelatedFieldService` 执行校验逻辑 - `@RelatedSheet`:标记该类的校验需要参考其他 Sheet;实现 `ValidatedRelatedSheetService`,框架会传入所有 Sheet 的数据 `Map> dataMap` ### Excel 列映射 使用 `@ExcelProperty(index = n)` 注解进行字段-列映射: ```java public class Student { @ExcelProperty(index = 0) @NotBlank(message = "名字不能为空") private String name; @ExcelProperty(index = 1) private String age; @ExcelProperty(index = 2) @InList(values = {"一班","二班"}, message = "班级错误") private String studentClass; @ExcelProperty(index = 3) private String source; } ``` ## API 参考 ### CheckExcelUtil - `List checkExcelData(String filePath, Class t, String toFilePath)` - `InputStream checkExcelDataToWeb(InputStream in, Class t)` - `List checkExcelData(InputStream in, Class t)`:当返回的 Map 中 `RES` 为 true 时返回空,否则返回数据列表 - 指定模板/起始行: - `List checkExcelData(String filePath, Class t, int row, String templateFilePath, String toFilePath)` - `InputStream checkExcelDataToWeb(InputStream in, Class t, int row, InputStream templateIn)` - 多 Sheet: - `Map> checkExcelAllSheet(InputStream in, String toFilePath, Class... classes)` - `Map> checkExcelAllSheet(InputStream in, InputStream templateIn, String toFilePath, Integer[] rows, Class[] classes)` - `InputStream checkExcelAllSheetToWeb(InputStream in, Class... classes)` - `InputStream checkExcelAllSheetToWeb(InputStream in, InputStream templateIn, Integer[] rows, Class[] classes)` - 只读取数据: - `Map> getMultiSheetData(String filePath, Class... classes | InputStream in, Class... classes)` - `List getData(String filePath, Class t)` ### CheckDataUtil - `void checkData(E t, Class... groups)`:失败抛出首个错误信息 - `Map checkDataToField(E t, Class... groups)`:返回字段→错误消息 - `void multiCheckData(List dataList, Class... groups)` ### ValidatorUtils - `void initialize()`:初始化 Hibernate Validator,若失败降级为简单校验实现(不报错) - `Set> validateEntity(Object o, Class... groups)` - `Map getValidatedObject(Object o, Class... groups)` - 注册服务(通常通过 `ServiceRegistry` 调用): - `registerFieldService(ValidatedRelatedFieldService s)` - `registerSheetService(ValidatedRelatedSheetService s)` - `registerConvertService(ConvertObjectService s)` ### ServiceRegistry(非 Spring 环境服务注册器) - 单个注册:`registerFieldService`、`registerSheetService`、`registerConvertService` - 批量注册:`registerFieldServices`、`registerSheetServices`、`registerConvertServices` - 查询/清空:`getFieldServices`、`getSheetServices`、`getConvertServices`、`clearAll` ### 扩展接口 - `ValidatedRelatedFieldService # boolean validator(T value)` - `ValidatedRelatedSheetService # boolean validator(Map> dataMap, T value)` - `ConvertObjectService # T convert(S source)`(见 `convertObject` 包) ### 违规则工具 - `ViolationUtils.addViolation(String fieldName, String message)`:在服务中报告字段错误,返回 `false`/`true` 以指示校验流程继续/通过 ## 进阶示例 ### 指定 Excel → 模板 → 输出 ```java List ok = CheckExcelUtil.checkExcelData( "/path/input.xlsx", Student.class, 2, // 第3行起校验(从0开始) "/path/template.xlsx", "/path/result.xlsx" ); ``` ### 多 Sheet + 模板 + 各 Sheet 不同起始行 ```java try (FileInputStream in = new FileInputStream("/path/input.xlsx"); FileInputStream tpl = new FileInputStream("/path/template.xlsx")) { Integer[] rows = {1, 2, 1}; // 各Sheet起始校验行 Class[] classes = {Student.class, StudentClass.class, Teacher.class}; Map> okMap = CheckExcelUtil.checkExcelAllSheet(in, tpl, "/path/result.xlsx", rows, classes); } ``` ### Web 场景(直接返回错误标注后的工作簿流) ```java try (FileInputStream in = new FileInputStream("/path/input.xlsx")) { InputStream wb = CheckExcelUtil.checkExcelDataToWeb(in, Student.class); // 将 wb 写入响应输出流 } ``` ### 对象转换 ```java @Service public class ConvertStudentService implements ConvertObjectService { @Override public StudentTest convert(Student student) { StudentTest studentTest = new StudentTest(); studentTest.setName(student.getName()); studentTest.setAge(Integer.valueOf(student.getAge())); studentTest.setClassNo(1); return studentTest; } } ``` ## 最佳实践 - 在应用启动阶段调用一次 `ValidatorUtils.initialize()` - 非 Spring 场景下,所有自定义服务通过 `ServiceRegistry` 注册一次即可;测试用例记得 `clearAll()` 清理 - `@ExcelProperty(index = n)` 可用于字段-列映射;若不设置,默认按实体属性声明顺序匹配列 - 关联校验中避免抛异常,使用 `ViolationUtils.addViolation` 精确标注字段错误,提升用户定位体验 - 对大文件使用多 Sheet 方式、流式 SXSSFWorkbook,避免内存压力 - 对象转换放在成功数据管道末端,配合 `ConvertObjectService` 实现解耦 ## 常见问题(FAQ) - **Q: 忘记 `initialize()` 会怎样?** - A: 首次校验前会自动尝试初始化;若 Hibernate Validator 初始化失败,将退回简单校验(不报错),建议在启动期显式初始化并确认依赖 - **Q: 返回的成功数据在哪里?** - A: 当校验失败时,工具主要输出带错误标注的 Excel;需要"成功数据"时请使用 `checkExcelData(...)` 的 List 返回或 `getData(...) / getMultiSheetData(...)` - **Q: 如何在 Web 端直接下载错误标注表格?** - A: 使用 `checkExcelDataToWeb(...)` 或 `checkExcelAllSheetToWeb(...)` 获取 `InputStream`,写入 HTTP 响应即可 - **Q: 多 Sheet 指定行数和类数组长度不一致?** - A: 框架会抛出 `IllegalArgumentException`,请确保两者长度一致并按 Sheet 顺序一一对应 ## 版本与兼容性 - JDK 版本:参考你的项目 JDK 环境;实际以 `pom.xml` 为准 - 依赖版本:建议使用较新的 Hibernate Validator 与 POI;若需 Jakarta/Javax 适配,请统一家族版本 ## 许可 参见仓库 `LICENSE`