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