代码一:
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();}
}