EasyExcel實現(xiàn)導入+各種數(shù)據(jù)校驗功能
實現(xiàn)的功能
1.導入非xls和xlsx格式的文件
2.導入空數(shù)據(jù)的excel文件
3.數(shù)據(jù)缺失
4.導入的excel文件中有重復的數(shù)據(jù)
5.導入的excel文件數(shù)據(jù)錯誤
6.導入的模板不是正確模板
前置條件: 1)傳的參數(shù)是 MultipartFile file
2)編寫一個接收excel文件的實體類,保證@ExcelProperty(“表頭1”)中的屬性和excel導入的一致
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ConfigVO {
@ExcelProperty("表頭1")
private String head1;
@ExcelProperty("表頭2")
private String head2;
}
3)在Impl中使用EasyExcel讀數(shù)據(jù),就會執(zhí)行監(jiān)聽器
EasyExcel.read(multipartFile.getInputStream(), ConfigVO.class, new ConfigListener(this)).sheet().doRead();
4)自定義監(jiān)聽器
@Slf4j
public class ConfigListener extends AnalysisEventListener<ConfigVO> {
private static int count = 0;
List<ConfigVO> list = new ArrayList<>();
// 此map用來存儲模板錯誤的提示,由于我的全局異常捕獲沒有處理在監(jiān)聽器內拋出的異常信息,
//所以就將數(shù)據(jù)挪到service層處理拋異常
Map<String, String> errMap = new HashMap<>();
@Autowired
private IConfigService configcService;
public ConfigListener(ConfigService configService) {
this.configService = configService;
}
@Override
public void invoke(ConfigVO configVO, AnalysisContext analysisContext) {
count++;
list.add(configVO);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("成功讀取" + count + "條數(shù)據(jù)");
//保存讀取到的數(shù)據(jù)到serviceImpl處理
configService.saveConfig(list, errMap);
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 驗證表頭
String head1 = "表頭1";
String head2 = "表頭2";
if (headMap.size() <= 0) {
errMap.put("msg", "導入的模板不符合,請檢查后重新導入!");
}
//value值才是表頭信息
if (!headMap.containsValue(head1) || !headMap.containsValue(head2)) {
errMap.put("msg", "導入的模板不符合,請檢查后重新導入!");
}
}
}5)serviceImpl層處理單個數(shù)據(jù)校驗+存儲
public void saveConfig(List<ConfigVO> list, Map<String, String> errMap) {
//批量存儲數(shù)據(jù)的list
List<ConfigVO> customerlist = new ArrayList<>();
//提示錯誤的list
List<Integer> errList = new ArrayList<>();
//用來去重的map
Map<String, Integer> map = new HashMap<>();
//遍歷list進行校驗
for (int i = 0; i < list.size(); i++) {
//原因是因為我想獲取出錯的當前行,但是excel表格是從1開始,一條數(shù)據(jù)就是2
Integer count = 2;
count = count + i;
ConfigVO configVO = list.get(i);
//判有無空數(shù)據(jù)
if (!ObjectUtils.isEmpty(configVO.getHead1()) && !ObjectUtils.isEmpty(configVO.getHead2())) {
//判類型是否錯誤
if (("1").equals(configVO.getHead1()) || ("2").equals(configVO.getHead1())) {
String customerName = configVO.getHead2();
//去前后空格
customerName = StrUtil.trim(customerName);
//校驗單個數(shù)據(jù)是否超出字數(shù)限制
if (customerName.length() > 255) {
errList.add(count);
}
//map去重的key
String mapStr = configVO.getHead2() + ":" + configVO.getHead1();
//去除excel中重復數(shù)據(jù)
if (map.containsKey(mapStr)) {
//如果已經(jīng)有了,那說明有重復數(shù)據(jù),更新行數(shù)為最新的
map.put(mapStr, count);
//放到錯誤提示的list,遍歷展示錯誤
errList.add(map.get(mapStr));
} else {
//沒有重復也放到map中便于去重
map.put(mapStr, count);
//放到需要存儲的list
customerlist.add(configVO);
}
} else {
errList.add(count);
}
} else {
errList.add(count);
}
}
//判斷是否是錯誤模板
if (!errMap.isEmpty()) {
throw new CommonException(errMap.get("msg"));
}
//是否有導入錯誤的數(shù)據(jù)
if (!errList.isEmpty()) {
StringBuilder str = new StringBuilder();
str.append("第");
for (Integer err : errList) {
str.append("" + err + "行,");
}
str.append("導入失敗,請確認信息是否有誤或數(shù)據(jù)是否有重復");
throw new CommonException(str.toString());
} else {
//需要存到數(shù)據(jù)庫的數(shù)據(jù)
//查數(shù)據(jù)庫查是否已經(jīng)存在
//存在就跳過,不存在就添加到list
}
//新增數(shù)據(jù)到數(shù)據(jù)庫
}
}
}1.導入非xls和xlsx格式的文件
//獲取文件名+后綴
String filename = file.getOriginalFilename();
if (filename != null) {
//獲取其后綴
String extension = filename.substring(filename.lastIndexOf(".") + 1);
if (!(extension.equals("xls") || extension.equals("xlsx"))) {
//此處為自定義異常捕獲,可使用其他方式
throw new CommonException("文件格式有誤,請檢查上傳文件格式!!");
}
}2.導入空數(shù)據(jù)的excel文件
//校驗導入的是空模板
try {
InputStream inputStream = file.getInputStream();
ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
int rowCount = reader.getRowCount();
if (rowCount <= 1) {
throw new CommonException("導入的為空模板,請檢查后重新導入!!");
}
}catch (IOException e) {
log.error("文件獲取失敗:{}", e);
throw new CommonException(e.getMessage());
}3.導入的模板不是正確模板
判斷導入的excel是否是提供的表
使用EasyExcel實現(xiàn)
1)首先要自定義監(jiān)聽器,繼承AnalysisEventListener<轉換excel的對象>
2)實現(xiàn)他的三個方法
invoke 逐行解析excel,每一行都會執(zhí)行
doAfterAllAnalysed 解析完全部的excel,會調用該方法
invokeHeadMap 驗證表頭的方法
3)在invokeHeadMap方法中編寫
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 驗證表頭
String head1 = "表頭1";
String head2 = "表頭2";
if (headMap.size() <= 0) {
errMap.put("msg", "導入的模板不符合,請檢查后重新導入!");
}
//value值才是表頭信息
if (!headMap.containsValue(head1) || !headMap.containsValue(head2)) {
errMap.put("msg", "導入的模板不符合,請檢查后重新導入!");
}
}headMap中存放的就是導入的excel全部的表頭信息,
只要判斷hashMap中是否包含我們的表頭就可以校驗是否是我們提供的模板
到此這篇關于EasyExcel實現(xiàn)導入+各種數(shù)據(jù)校驗的文章就介紹到這了,更多相關EasyExcel導入數(shù)據(jù)校驗內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot 使用Mongo的GridFs實現(xiàn)分布式文件存儲操作
這篇文章主要介紹了Spring Boot 使用Mongo的GridFs實現(xiàn)分布式文件存儲操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
GraalVM和Spring Native嘗鮮一步步讓Springboot啟動飛起來66ms完成啟動
GraalVM是高性能的JDK,支持Java/Python/JavaScript等語言,它可以讓Java變成二進制文件來執(zhí)行,讓程序在任何地方運行更快,這篇文章主要介紹了GraalVM和Spring Native嘗鮮一步步讓Springboot啟動飛起來66ms完成啟動,需要的朋友可以參考下2023-02-02

