检查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主数据*/@Setterprivate List<T> userExcelList = new ArrayList<>();/*** excel的主数据是在这个生命周期读取的*/@Overridepublic void invoke(T t, AnalysisContext analysisContext) {userExcelList.add(t);}/*** 解析完excel需要干的事情*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("已解析完所有数据!");}/*** excel头部数据*/@Overridepublic 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.mzph.cn/news/582971.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL库的操作】

1.库的操作 1.1 创建数据库 语法&#xff1a; create databases [IF NOT EXISTS] 数据库名;注意&#xff1a; [] 是可选项 1.2 创建数据库案例 创建名为 db1 的数据库 create databases db1;说明&#xff1a;当我们创建数据库没有指定字符集和校验规则时&#xff0c;系统…

docker compose 部署 grafana + loki + vector 监控kafka消息

Centos7 随笔记录记录 docker compose 统一管理 granfana loki vector 监控kafka 信息。 当然如果仅仅是想通过 Grafana 监控kafka&#xff0c;推荐使用 Grafana Prometheus 通过JMX监控kafka 目录 1. 目录结构 2. 前提已安装Docker-Compose 3. docker-compose 自定义服…

Go 泛型之泛型约束

Go 泛型之泛型约束 文章目录 Go 泛型之泛型约束一、引入二、最宽松的约束&#xff1a;any三、支持比较操作的内置约束&#xff1a;comparable四、自定义约束五、类型集合&#xff08;type set&#xff09;六、简化版的约束形式七、约束的类型推断八、小结 一、引入 虽然泛型是…

Keras多分类鸢尾花DEMO

完整的一个小demo&#xff1a; pandas1.2.4 numpy1.19.2 python3.9.2 import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas import DataFrame from scipy.io import loadmat from sklearn.model_selection import train_test_split impor…

【MYSQL】MYSQL 的学习教程(十)之 InnoDB 锁

数据库为什么需要加锁呢&#xff1f; 如果有多个并发请求存取数据&#xff0c;在数据就可能会产生多个事务同时操作同一行数据。如果并发操作不加控制&#xff0c;不加锁的话&#xff0c;就可能写入了不正确的数据&#xff0c;或者导致读取了不正确的数据&#xff0c;破坏了数…

MySQL数据库多版本并发控制(MVCC)

在数据库中&#xff0c;并发控制是确保多个事务能够同时执行&#xff0c;而不会导致数据不一致或冲突的关键机制。多版本并发控制(MVCC)是一种流行的并发控制方法&#xff0c;它可以允许多个事务同时读取同一数据项的不同版本&#xff0c;而不会相互阻塞。本文将讨论MVCC的原理…

在 iPhone 手机上恢复数据的 7 个有效应用程序

我们的生活离不开 iPhone。无论我们走到哪里&#xff0c;他们都陪伴着我们&#xff0c;让我们保持联系、拍摄照片和视频&#xff0c;并提供娱乐。与此同时&#xff0c;您将计算机安全地放在办公桌上&#xff0c;不受天气影响&#xff0c;也不受伤害。如果您要在任何地方丢失重要…

【ES】Elasticsearch常见问题与解决(持续更新)

目录 Elasticsearch常见问题 1. 集群健康问题 2. 性能问题 3. 映射问题 4. 分片问题 5. 内存问题 6. 硬件问题 7. 配置问题 8. 安全问题 9. 网络问题 10. 版本不兼容 Elasticsearch日常使用小结 【Q】离线告警&#xff0c;有IP已离线 【Q】统计某个应用的某个索引…

Android 13 - Media框架(28)- MediaCodec(三)

上一节我们了解到 ACodec 执行完 start 流程后&#xff0c;会把所有的 input buffer 都提交给 MediaCodec 层&#xff0c;MediaCodec 是如何处理传上来的 buffer 呢&#xff1f;这一节我们就来了解一下这部分内容。 1、ACodecBufferChannel::fillThisBuffer ACodec 通过调用 A…

Java 代理模式

一、代理模式概述 代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问&#xff0c;这样就可以在不修改原目标对象的前提下&#xff0c;提供额外的功能操作&#xff0c;扩展目标对象的功能。 代理模式的主要作用是扩展目标…

Linux中proc文件系统相关介绍

proc虚拟文件系统的工作原理 linux 内核是一个非常庞大、非常复杂的一个单独的程序&#xff0c;对于这样一个程序来说调试是非常复杂的。像kernel这样庞大的项目&#xff0c;给里面添加或者修改一个功能是非常麻烦的&#xff0c;因为添加一个功能可能会影响其他已经有的功能。…

3D动态路障生成

3D动态路障生成 介绍设计实现1.路面创建2.空物体的创建3.Create.cs脚本创建 总结 介绍 上一篇文章介绍了Mathf.Lerp的底层实现原理&#xff0c;这里介绍一下跑酷类游戏的动态路障生成是如何实现的。 动态路障其实比较好生成&#xff0c;但是难点在哪里&#xff0c;如果都是平面…

JMeter逻辑控制器之While控制器

JMeter逻辑控制器之While控制器 1. 背景2.目的3. 介绍4.While示例4.1 添加While控制器4.2 While控制器面板4.3 While控制器添加请求4.3 While控制器应用场景 1. 背景 存在一些使用场景&#xff0c;比如&#xff1a;某个请求必须等待上一个请求正确响应后才能开始执行。或者&…

Idea如何从磁盘中应用 下载好的插件流程,安装zip压缩包。

1、将下载的插件文件&#xff08;通常是一个ZIP文件&#xff09;复制到IntelliJ IDEA的“plugins”文件夹中。 IDEA版本 2、重启IntelliJ IDEA。 3、在设置窗口中&#xff0c;选择左侧的“Plugins”。 4、选择之前复制到“plugins”文件夹中的插件文件&#xff0c;点击“OK”按…

基于Wenet长音频分割降噪识别

Wenet是一个流行的语音处理工具&#xff0c;它专注于长音频的处理&#xff0c;具备分割、降噪和识别功能。它的长音频分割降噪识别功能允许对长时间录制的音频进行分段处理&#xff0c;首先对音频进行分割&#xff0c;将其分解成更小的段落或语音片段。接着进行降噪处理&#x…

深入理解二分查找算法(一)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前实时帧率(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的帧率的技术背景Baumer工业相机的帧率获取方式CameraExplorer如何查看相机帧率信息在NEOAPI SDK里通过函数获取相机帧率 Baume…

Android Studio新手实战——深入学习Activity组件

目录 前言 一、Activity简介 二、任务栈相关概念 三、常用Flag 四、结束当前Activity 五、Intent跳转Activity 六、更多资源 前言 Android是目前全球最流行的移动操作系统之一&#xff0c;而Activity作为Android应用程序的四大组件之一&#xff0c;是Android应用程序的核…

JAX: 快如 PyTorch,简单如 NumPy - 深度学习与数据科学

JAX 是 TensorFlow 和 PyTorch 的新竞争对手。 JAX 强调简单性而不牺牲速度和可扩展性。由于 JAX 需要更少的样板代码&#xff0c;因此程序更短、更接近数学&#xff0c;因此更容易理解。 长话短说&#xff1a; 使用 import jax.numpy 访问 NumPy 函数&#xff0c;使用 import …

华为云CCE-集群内访问-根据ip访问同个pod

华为云CCE-集群内访问-根据ip访问同个pod 问题描述&#xff1a;架构如下&#xff1a;解决方法&#xff1a; 问题描述&#xff1a; 使用service集群内访问时&#xff0c;由于启用了两个pod&#xff0c;导致请求轮询在两个pod之间&#xff0c;无法返回正确的结果。 架构如下&am…