检查Excel内容是否符合规范

news/2024/7/21 5:23:13 标签: excel

代码一:

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);
    }

}

代码二:

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();
    }
}


http://www.niftyadmin.cn/n/5290544.html

相关文章

Postman接口测试工具使用

一、前言 在前后端分离开发时&#xff0c;后端工作人员完成系统接口开发后&#xff0c;需要与前端人员对接&#xff0c;测试调试接口&#xff0c;验证接口的正确性可用性。而这要求前端开发进度和后端进度保持基本一致&#xff0c;任何一方的进度跟不上&#xff0c;都无法及…

gin框架使用系列之五——表单校验

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》 一 、表单验证的基本理论 在第三篇中&#xff0c;我们介绍了如何…

室内设计师效果图云渲染好?还是本地渲染好?

室内设计师在设计项目中经常面临一个关键的技术选择&#xff1a;使用云渲染服务或本地渲染完成效果图渲染呢&#xff1f;每种方式都有其独的优势与不足&#xff0c;且影响整个设计的完成速度、质量和成本。当然还有部分人群不知道云渲染是什么&#xff1f;本文整理关于云渲染的…

03.MySQL的体系架构

MySQL的体系架构 一、MySQL简介二、MySQL的体系架构三、MySQL的内存结构四、MySQL的文件结构 一、MySQL简介 MySQL是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;后被Sun公司收购&#xff0c;Sun公司被Oracle…

学习笔记 k8s常用kubectl命令

k8s常用kubectl命令 pod 相关强制删除pod查看 Pod 中指定容器的日志pod 扩容 etcd 备份集群设置集群上下文配置文件切换集群 节点cordondrain pod 相关 强制删除pod pod 状态terminal了&#xff0c;需要强制删除 kubectl delete pod <pod_name> --grace-period0 --force…

BAT log-yyyy-mm-dd.log

日志文件 文件名 日期格式化 https://download.csdn.net/download/spencer_tseng/88673716

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPISDK中UserSet的技术背景代码案例分享第一步&#xff1a;保存相机当前参数设置UserSet_Save第二步&#xff1a;载入已经保…

【数据结构和算法】---二叉树(2)--堆的实现和应用

目录 一、堆的概念及结构二、堆结构的实现2.1堆向下调整算法2.2堆向上调整算法2.3删除堆顶元素2.4插入元素2.5其他函数接口 三、堆结构的应用3.1堆排序3.2Top-k问题 四、堆概念及结构相关题目 一、堆的概念及结构 如果有一个数字集合&#xff0c;并把它的所有元素按完全二叉树…