# 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**: 11 - **Forks**: 0 - **Created**: 2024-02-05 - **Last Updated**: 2025-02-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: Excel, Java, java-util, Excel工具 ## README # cc-excel-util ## 介绍 cc-excel-util一个简单Excel导入数据校验工具,支持`hibernate`注解校验,并支持多属性关联校验和多sheet校验, 并且还支持`sheet`关联属性校验。只需要添加注解,实现对应的接口即可,不用用户写大量的校验逻辑。 ## 快速开始 下载源码打成jar包,引入即可使用 ### 单sheet校验 - 创建测试数据 ![image text](/doc/imgs/1.png) - 编写对应的实体类, ```java @Data public class Student { @NotBlank(message = "名字不能为空") private String name; private String age; @InList(values = {"一班","二班"},message = "班级错误") private String studentClass; private String source; } ``` - 调用`checkExcelData`方法 ```java /** * @param filePath 读取文件路径 * @param t 校验实体 * @param toFilePath 保存文件路径 * @param * @throws Exception */ void checkExcelData(String filePath, Class t, String toFilePath) ``` ```java String path = "C:\\Users\\XXX\\Desktop\\"; @Test public void test1() throws Exception { String file = path+"test.xlsx"; CheckExcelUtil.checkExcelData(file,Student.class,path+"result.xlsx"); } ``` - 查看结果 ![image text](/doc/imgs/2.png) #### 其中也可以在对象上添加 `@ExcelProperty`注解,来将excel中的数据与实体属性对应,如果不设置默认按照实体类属性排序 ```java @Data public class Student { @ExcelProperty(index = 1) private String age; @ExcelProperty(index = 2) @InList(values = {"一班","二班"},message = "班级错误") private String studentClass; @ExcelProperty(index = 0) @NotBlank(message = "名字不能为空") private String name; @ExcelProperty(index = 3) private String source; } ``` ### 属性关联校验 有时候对象属性需要根据另一个属性值进行判断,可以使用属性关联校验。 *例子:* 现在我们判断如果一个学生的分数超过90但是没有分配到一班,显示分配班级错误 - 在类上添加`RelatedClass`注解 ```java @Data @RelatedClass public class Student { @ExcelProperty(index = 1) private String age; @ExcelProperty(index = 2) private String studentClass; @ExcelProperty(index = 0) @NotBlank(message = "名字不能为空") private String name; @ExcelProperty(index = 3) private String source; } ``` - 实现`ValidatedRelatedFieldService`接口,将校验错误的数据使用`ViolationUtils.addViolation`方法返回,其中`fileName`对应校验失败的属性,`message`校验失败的消息 ```java @Service public class TestValidateFieldService implements ValidatedRelatedFieldService{ @Override public boolean validator(Student value) { System.out.println("当前对象"+value); Integer source = Integer.parseInt(value.getSource()); String studentClass = value.getStudentClass(); if(source>=90&&!studentClass.equals("一班")){ reutrn ViolationUtils.addViolation("studentClass","班级分配错误"); } return true; } } ``` - 查看结果 ![image text](/doc/imgs/3.png) ### 多sheet属性关联校验 当存在多个sheet时,我们需要一次对多个sheet做校验 - 添加添加`StudentClass`类,并添加`@RelatedClass`注解 ```java @Data @RelatedClass public class StudentClass { private String name; private String nums; } ``` - 分别对`Student`和`StudentClass`实现不同的校验逻辑 如果学生表中有学生名称是`zhangsan`则验证错误 ```java @Service public class ValidatedRelatedFieldServiceStudent implements ValidatedRelatedFieldService { @Override public boolean validator(Student value) { if (value.getName().equals("zhangsan")) { return ViolationUtils.addViolation("name", "名字错误"); } return true; } } ``` 如果班级表中班级名称是`一班`则验证错误 ```java @Service public class ValidatedRelatedFieldServiceStudentClass implements ValidatedRelatedFieldService { @Override public boolean validator(StudentClass value) { if (value.getName().equals("一班")) { return ViolationUtils.addViolation("name", "班级错误"); } return true; } } ``` - 观察结果 ![image text](/doc/imgs/6.png) ![image text](/doc/imgs/7.png) ### sheet之间的数据关联校验 有时候一个sheet对应的对象需要根据另一个sheet对应的对象属性值进行修改,可以使用多sheet关联校验。 - 添加测试数据 ![image text](/doc/imgs/4.png) - 添加`StudentClass`类,并在类上添加`RelatedSheet`注解 ```java @Data @RelatedSheet public class StudentClass { private String className; private String nums; } ``` - 实现`RelatedSheetValidator`接口 *例子:* 现在我们判断如果一个学生的班级不在所有班级中,在班级table中显示有学生班级信息错误 ```java @Service public class TestValidateSheetService implements ValidatedRelatedSheetService { @Override public boolean validator(Map> dataMap, StudentClass o) { System.out.println(dataMap); System.out.println(o); List objects = dataMap.get(0); String className = o.getClassName(); List students = ObjectUtils.sourceToTarget(objects, Student.class); List collect = students.stream().map(Student::getStudentClass).collect(Collectors.toList()); if(!collect.contains(className)){ return ViolationUtils.addViolation("className","有学生班级错误"); } return true; } } ``` - 调用`checkExcelMultiSheet`方法 ```java @Test public void test1() throws Exception { String file = path+"test.xlsx"; FileInputStream inputStream = new FileInputStream(file); Map> map =new HashMap<>(); map.put(0,Student.class); map.put(1,StudentClass.class); CheckExcelUtil.checkExcelMultiSheet(inputStream,path+"result.xlsx",map); } ``` - 观察结果 ![image text](/doc/imgs/5.png) ### 支持对象多属性联合校验 创建好对象,直接调用`CheckDataUtil.checkData`方法即可,一样实现`ValidatedRelatedFieldService`即可实现联合校验 ```java Student student = new Student(); student.setName("aaa"); student.setAge("12"); student.setClassName("yib"); student.setGrade("90"); CheckDataUtil.checkData(student); ``` ### 对象转化 当校验成功的数据需要做对象转化时,可以实现`ConvertObjectService`接口,将对象进行转化,泛型参数1代表转化之前的实体对象,参数2代码需要转化的对象 ```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; } } ``` ## 后期优化 第一版可能会有些bug,后续慢慢优化并增加新的功能...