【EasyExcel】easyExcel 检查表头是否匹配 封装了easyExcel的工具类,包含字段校验功能,可使用validate校验

1.excel基类,统一存储行号字段

import lombok.Data;

/**
 * excel基类,统一存储行号字段
 */
@Data
public class BaseExcelDto {

    private Integer rowNumber;

}

2.业务校验的接口

import java.util.*;

/**
 * 业务校验的接口
 */
public interface BusinessValidator {
    /**
     业务校验(校验数据是否符合业务要求,比如;用户不能重复)
     @param excelData
     @return
     */
    ImportResult validate(List excelData);
    
}

3.导入结果类

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import lombok.Data;

import java.util.List;

@Data
public class ImportResult {
    
    // 导入状态,全部成功true,有失败几率false
    private Boolean importStatus;

    // 成功记录(校验合法的数据)
    private List successData;

    // 检验不合法的数据
    private List failedData;

    // 错误信息
    private List failedMsg;

    //
    public Boolean getImportStatus() {
        return CollectionUtils.isEmpty(failedData);
    }
}

4.ExcelModelListener(excel监听)

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 三十七度
 */
public class ExcelModelListener extends AnalysisEventListener{


        private Class classz;

        private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

        private final Validator beanValidator = factory.getValidator();

        private List failedMsg;

        private Map head;

        private static final String ERR_MSG = "第--%d--行";

        private ArrayList failedList = new ArrayList<>();

        private ArrayList successList = new ArrayList<>();

        public ExcelModelListener(Map headMap, Class c) {

            failedMsg = new ArrayList<>();

            head = headMap;

            classz = c;

        }


        /**
         * 解析行数据时做必填校验
         *
         * @param
         * @param
         */
        @Override
        public void invoke(Object data, AnalysisContext context) {
            int rouNumber = context.readRowHolder().getRowIndex() + 1;
            Method method = BeanUtils.findMethod(data.getClass(), "setRowNumber", Integer.class);
            if (null != method) {
                try {
                    method.invoke(data, rouNumber);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            // TODO
            Set<ConstraintViolation<Object>> violationSet = beanValidator.validate(data);

            if (!CollectionUtils.isEmpty(violationSet)) {
                List messages = violationSet.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList());
                String join = org.apache.commons.lang3.StringUtils.join(messages, ",");
                failedMsg.add(String.format(ERR_MSG, rouNumber) + ":" + join);
                failedList.add(data);
            } else {
                successList.add(data);
            }

        }


        /**
         * 校验表头
         *
         * @param context
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            if (null == head) {
                try {
                    head = getIndexNameMap(classz);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }

            if (CollectionUtils.isEmpty((Collection) head)) {
                return;
            }

            Set keySet = head.keySet();
            for (Object key : keySet) {
                if (StringUtils.isEmpty((CharSequence) head.get(key))) {
                    throw new ExcelAnalysisException("解析excel出错,请传入正确格式的excel");
                }

                if (!head.get(key).equals(head.get(key))) {
//                    log.info(head.get(key));
                    System.out.println(head.get(key));
                    throw new ExcelAnalysisException("解析excel出错,请传入正确格式的excel");

                }
            }
        }


        public static Map getIndexNameMap(Class clazz) throws NoSuchFieldException {

            Map result = new HashMap<>();
            Field field;
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                field = clazz.getDeclaredField(fields[i].getName());
                field.setAccessible(true);
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                if (excelProperty != null) {
                    int index = excelProperty.index();
                    String[] values = excelProperty.value();
                    StringBuilder value = new StringBuilder();
                    for (String v : values) {
                        value.append(v);
                    }
                    result.put(index, value.toString());
                }
            }

            return result;

        }

}

5.excelUtils(工具)

import com.alibaba.excel.EasyExcel;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Map;

@Slf4j
public class ExcelUtil {

    /**
     * 导入Excel并做数据校验
     *
     * @param in                Excel文件输入流
     * @param t                 返回对象的泛型
     * @param businessValidator 业务校验的接口(自主去实现业务校验,比如:导入的用户是否已存在)
     * @param sheetNumber       第几个sheet,从0开始
     * @param headNumber        表头行号,从1开始
     * @param headMap           表头描述,map的key是第几列(从0开始),value是表头第几列对应的内容,用来校验Excel格式,如果不传,则取返回实体@ExcelProperty的value属性做校验
     * @param
     * @return
     */

    public static ImportResult importExcelAndValidate(InputStream in, T t, BusinessValidator businessValidator, int sheetNumber, int headNumber, Map headMap) {


        ExcelModelListener modelListener = new ExcelModelListener(headMap, t.getClass());

        EasyExcel.read(in, t.getClass(), modelListener).sheet(sheetNumber).headRowNumber(headNumber).doRead();

        ArrayList successList = modelListener.successList;

        ImportResult result = businessValidator.validate(successList);

        if (result == null) {

            result = new ImportResult<>();

            result.setFailedData(modelListener.failedList);

            result.setFailedMsg(modelListener.failedMsg);

            result.setSuccessData(successList);

        } else {

            if (!CollectionUtils.isEmpty(result.getFailedData())) {

                result.getFailedData().addAll(modelListener.failedList);
                result.getFailedMsg().addAll(modelListener.failedMsg);

            } else {

                result.setFailedMsg(modelListener.failedMsg);
                result.setFailedData(modelListener.failedList);

            }

        }

        return result;

    }
}

全部已整理好,希望能够帮助需要的人,创作不易(转载请表明出处),有问题请评论区留言。

👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
您好,对于使用 EasyExcel 进行导入文件的表头校验,您可以按照以下步骤进行操作: 1. 导入 EasyExcel 相关的依赖包,如果您使用 Maven 进行项目管理,可以在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.3.0</version> </dependency> ``` 2. 创建一个实现了 AnalysisEventListener 接口的监听器类,用于处理读取 Excel 数据时的回调操作。在该监听器类中,可以实现校验表头的逻辑。以下是一个简单的示例: ```java public class MyExcelListener extends AnalysisEventListener<Map<Integer, String>> { private boolean headerValid = false; private List<String> expectedHeaders; public MyExcelListener(List<String> expectedHeaders) { this.expectedHeaders = expectedHeaders; } @Override public void invoke(Map<Integer, String> rowData, AnalysisContext context) { if (!headerValid) { validateHeader(rowData); headerValid = true; } else { // 处理正常的行数据 // ... } } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 数据解析完成后的操作 // ... } private void validateHeader(Map<Integer, String> rowData) { List<String> actualHeaders = new ArrayList<>(rowData.values()); if (!actualHeaders.equals(expectedHeaders)) { throw new IllegalArgumentException("表头校验失败"); } } } ``` 3. 在您的业务代码中,使用 EasyExcel 进行文件的读取,并将监听器传入进行处理。以下是一个示例: ```java public void importExcel(File excelFile) { List<String> expectedHeaders = Arrays.asList("Header1", "Header2", "Header3"); try (InputStream inputStream = new FileInputStream(excelFile)) { ExcelReader reader = EasyExcel.read(inputStream).build(); reader.read(new Sheet(1, 1), new MyExcelListener(expectedHeaders)); // 读取第一个 sheet 的数据 } catch (Exception e) { // 异常处理 // ... } } ``` 在以上示例中,我们通过传入预期的表头名称列表来进行校验,如果实际的表头匹配预期,则会抛出异常。 希望以上内容对您有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿七度

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值