检查Excel内容是否符合规范

代码一:

java 复制代码
package com.ly.cloud.config;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author 
 * @Date Created in  2023/12/12 17:46
 * @DESCRIPTION:
 * @Version V1.0
 */
@Getter
@Slf4j
@Component
public class ExcelListenerConfig<T> extends AnalysisEventListener<T> {
    /**
     *  定义一个全局的读取header的map,方便其他地方使用改数据,当然要是你存进数据库那就更方便取了
     */
    private final Map<Integer, String> userHeaderMap = new HashMap<>();
    /**
     * excel主数据
     */
    @Setter
    private List<T> userExcelList = new ArrayList<>();

    /**
     * excel的主数据是在这个生命周期读取的
     */
    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        userExcelList.add(t);
    }

    /**
     * 解析完excel需要干的事情
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("已解析完所有数据!");
    }

    /**
     * excel头部数据
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 存到全局的map中
        userHeaderMap.putAll(headMap);
    }

}

代码二:

java 复制代码
package com.ly.cloud.util;

import com.alibaba.excel.EasyExcel;
import com.ly.cloud.config.ExcelListenerConfig;
import com.ly.cloud.dto.PzrtExportDto;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.bind.ValidationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author 
 * @Date Created in  2023/12/12 17:11
 * @DESCRIPTION: 检查传入的文件格式【文件格式,预期的参数列, 文件头内容, 文件头顺序】是否符合要求
 * @Version V1.0
 */

public class ExcelValidator {
    private static final Logger logger = LoggerFactory.getLogger(ExcelValidator.class);
    /**
     * 允许的文件格式
     */
    private static final List<String> ALLOWED_EXTENSIONS = Collections.singletonList("xlsx");
    /**
     * 预期的文件列
     */
    private static final Integer COLUMN_COUNT = 12;
    /**
     * 预期的参数列
     */
    private static final List<String> EXPECTED_HEADERS = Arrays.asList(
            "序号", "单位编号", "所属单位", "印信事项类别编号", "印信事项类别", "业务经办人名称", "业务分管领导", "业务正职领导", "分管校领导", "主要校领导", "版本号"
    );

    public static String validateExcelFile(MultipartFile file) throws IOException, InvalidFormatException {
        // 校验文件是否为空
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("文件不允许为空");
        }

        // 校验文件格式
        String fileExtension = getFileExtension(Objects.requireNonNull(file.getOriginalFilename()));
        if (!ALLOWED_EXTENSIONS.contains(fileExtension)) {
            throw new RuntimeException("文件格式有误");
        }
        // 校验文件内容
        try {
            ExcelListenerConfig listener = new ExcelListenerConfig();
            List userExcelList = listener.getUserExcelList();
            logger.info("拿到的集合内容是:{}", userExcelList.toString());
            // 读取 文件列头
            EasyExcel.read(file.getInputStream(), PzrtExportDto.class, listener).sheet(0).doRead();
            // 读取转成的Java对象
            logger.info("===========Excel Header数据===========");
            Map map = listener.getUserHeaderMap();
            Optional.ofNullable(map)
                    .ifPresent(headers -> {
                        headers.forEach((k, v) -> {
                            System.out.println("我的文件头格式是:" + k + v);
                            if (StringUtils.isEmpty(v) || !EXPECTED_HEADERS.contains(v)) {
                                logger.error("文件格式有误");
                                throw new RuntimeException("文件格式有误");
                            }
                        });
                    });
            //检查EasyExcel 表头顺序是否与规定得一致
            Map headerMap = listener.getUserHeaderMap();
            for (int i = 0; i < EXPECTED_HEADERS.size(); i++) {
                String expectedHeader = EXPECTED_HEADERS.get(i);
                String actualHeader = null;
                if (headerMap != null) {
                    actualHeader = (String) headerMap.get(i);
                }

                if (StringUtils.isEmpty(actualHeader) || !expectedHeader.equals(actualHeader)) {
                    logger.error("文件表头顺序有误");
                    throw new RuntimeException("文件表头顺序有误");
                }
            }

            //检查文件的列是否多余10列。
            Field[] fields = PzrtExportDto.class.getDeclaredFields();
            int columnCount = fields.length;
            logger.info("当前有几列:{}", columnCount);
            if (columnCount > COLUMN_COUNT) {
                throw new RuntimeException("文件格式有误");
            }
        } catch (IOException e) {
            throw new RuntimeException("文件格式有误" + e);
        }
        return "";
    }

    /**
     * 判断 一些文字是否用英文逗号隔开
     */
    public static void validateExcelData(List<?> excelList) {
        for (Object obj : excelList) {
            if (obj instanceof PzrtExportDto) {
                PzrtExportDto entity = (PzrtExportDto) obj;
                if (!isValidNamesOrEmpty(Optional.ofNullable(entity.getYwjbrmc()).orElse(""))) {
                    throw new RuntimeException("业务人名称格式不正确: " + entity.getYwjbrmc());
                }

                // 验证业务分管领导
                if (!isValidNamesOrEmpty(Optional.ofNullable(entity.getYwfgld()).orElse(""))) {
                    throw new RuntimeException("业务分格式不正确: " + entity.getYwfgld());
                }

                // 验证业务正职领导
                if (!isValidNamesOrEmpty( Optional.ofNullable(entity.getYwzzld()).orElse(""))) {
                    throw new RuntimeException("业务格式不正确: " + entity.getYwzzld());
                }

                // 验证分管校领导
                if (!isValidNamesOrEmpty(Optional.ofNullable(entity.getFgxld()).orElse(""))) {
                    throw new RuntimeException("分管格式不正确: " + entity.getFgxld());
                }

                // 验证主要校领导
                if (!isValidNamesOrEmpty(Optional.ofNullable(entity.getZyxld()).orElse(""))) {
                    throw new RuntimeException("主要格式不正确: " + entity.getZyxld());
                }
            }
        }
    }

    public static void main(String[] args) {
        String names = "";
        String regex = "^([\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\),)*[\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\)$";
//        String regex = "^([\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\),?)*[\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\)$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(names);
        boolean isMatch = matcher.find();

        System.out.println("格式是否匹配" + isMatch);
        System.out.println("=====" + isMatch);
    }
    /**
     * 验证多个姓名格式,用英文逗号隔开,允许为空
     */
    private static boolean isValidNamesOrEmpty(String names) {
        if (names.isEmpty()) {
            System.out.println(names);
            return true;
        }
        String regex = "^([\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\),)*[\\u4e00-\\u9fa5]+\\([a-zA-Z0-9]+\\)$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(names);
        boolean isMatch = matcher.find();

        System.out.println("格式是否匹配" + isMatch);
        System.out.println("=====" + isMatch);
        return isMatch;
    }



    private static String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf(".");
        if (lastDotIndex == -1) {
            return "";
        }
        return fileName.substring(lastDotIndex + 1).toLowerCase();
    }
}
相关推荐
弗拉唐7 小时前
将Excel文件的两个表格经过验证后分别读取到Excel表和数据库
数据库·excel
Lizzy_Fly7 小时前
【Excel】身份证号最后一位“X”怎么计算
excel
深情废杨杨7 小时前
后端-实现excel的导出功能(超详细讲解)
java·spring boot·excel
智汇探长7 小时前
EasyExcel自定义设置Excel表格宽高
java·excel·easyexcel
Eiceblue7 小时前
通过Python 调整Excel行高、列宽
开发语言·vscode·python·pycharm·excel
crackbuy7 小时前
Excel筛选的操作教程
excel
笔墨登场说说7 小时前
Excel SUMIFS
excel
Lizzy_Fly8 小时前
【Excel】ToRow超级查找函数
excel
mon_star°9 小时前
将答题成绩排行榜数据通过前端生成excel的方式实现导出下载功能
前端·excel
冰淇淋烤布蕾18 小时前
EasyExcel使用
java·开发语言·excel