检查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();
    }
}
相关推荐
徐同保14 小时前
vue 在线预览word和excel
vue.js·word·excel
kaixin_啊啊18 小时前
计算机二级office操作技巧——Excel篇
excel
~在杰难逃~1 天前
关于订单信息的Excel数据分析报告
笔记·数据分析·excel·数据分析报告
生产队队长2 天前
SpringBoot2:web开发常用功能实现及原理解析-整合EasyExcel实现Excel导入导出功能
spring boot·excel
麋鹿会飞但不飘2 天前
EasyExcel拿表头(二级表头)爬坑,invokeHeadMap方法
java·spring boot·excel
Eiceblue2 天前
Python 实现Excel XLS和XLSX格式相互转换
vscode·python·pycharm·excel
if时光重来2 天前
springboot项目实现导出excel动态设置表头
spring boot·后端·excel
我是Superman丶2 天前
【工具】Java Excel转图片
java·python·excel
說詤榢2 天前
判断2个excel文件差异的条数
excel
镜花照无眠2 天前
Excel爬虫使用实例-百度热搜
爬虫·excel