EasyExcel实现导入+各种数据校验功能
目录
- 实现的功能
- 1.导入非xls和xlsx格式的文件
- 2.导入空数据的excel文件
- 3.数据缺失
- 4.导入的excel文件中有重复的数据
- 5.导入的excel文件数据错误
- 6.导入的模板不是正确模板
- 1.导入非xls和xlsx格式的文件
- 2.导入空数据的excel文件
- 3.导入的模板不是正确模板
实现的功能
1.导入非xls和xlsx格式的文件
2.导入空数据的excel文件
3.数据缺失
4.导入的excel文件中有重复的数据
5.导入的excel文件数据错误
6.导入的模板不是正确模板
前置条件: 1)传的参数是 MultipartFile file
2)编写一个接收excel文件的实体类,保证@ExcelProperty(“表头1”)中的属性和excel导入的一致@Data @jsonIgnoreProperties(ignoreUnknown = true) public class Confi开发者_开发入门gVO { @ExcelProperty("表头1") private String head1; @ExcelProperty("表头2") private String head2; }
3)在Impl中使用EasyExcel读数据,就会执行监听器
EasyExcel.read(multipartFile.getInputStream(), ConfigVO.class, new ConfigListener(this)).sheet().doRead();
4)自定义监听器
@Slf4j public class ConfigListener extends AnalysisEventListener<ConfigVO> { private static int count = 0; List<ConfigVO> list = new ArrayList<>(); // 此map用来存储模板错误的提示,由于我的全局异常捕获没有处理在监听器内抛出的异常信息, //所以就将数据挪到service层处理抛异常 Map<String, String> errMap = new HashMap<>(); @Autowired private IConfigService configcService; public ConfigListener(ConfigService configService) php{ this.configService = configService; } @Override public void invoke(ConfigVO configVO, AnalysisContext analysisContext) { count++; list.add(configVO); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { log.info("成功读取" + count + "条数据"); //保存读取到的数据到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层处理单个数据校验+存储
public void saveConfig(List<ConfigVO> list, Map<String, String> errMap) { //批量存储数据的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开始,一条数据就是2 Integer count = 2; count = count + i; ConfigVO configVO = list.get(i); //判有无空数据 if (!ObjectUtils.isEmpty(configVO.getHead1()) && !ObjectUtils.isEmpty(configVO.getHead2())) { //判类型是否错误 if (("1").equals(configVO.getHead1()) || ("2").equals(configVO.getHead1())) { String cushttp://www.devze.comtomerName = configVO.getHead2(); //去前后空格 customerName = StrUtil.trim(customerName); //校验单个数据是否超出字数限制 if (customerName.length() > 255) { errList.add(count); } //map去重的key String mapStr = configVO.getHead2() + ":" + configVO.getHead1(); //去除excel中重复数据 if (map.containsKey(mapStr)) { 编程客栈 //如果已经有了,那说明有重复数据,更新行数为最新的 map.put(mapStr, coun编程t); //放到错误提示的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")); } //是否有导入错误的数据 if (!errList.isEmpty()) { StringBuilder str = new StringBuilder(); str.append("第"); for (Integer err : errList) { str.append("" + err + "行,"); } str.append("导入失败,请确认信息是否有误或数据是否有重复"); throw new CommonException(str.toString()); } else { //需要存到数据库的数据 //查数据库查是否已经存在 //存在就跳过,不存在就添加到list } //新增数据到数据库 } } }
1.导入非xls和xlsx格式的文件
//获取文件名+后缀 String filename = file.getOriginalFilename(); if (filename != null) { //获取其后缀 String extension = filename.substring(filename.lasjstIndexOf(".") + 1); if (!(extension.equals("xls") || extension.equals("xlsx"))) { //此处为自定义异常捕获,可使用其他方式 throw new CommonException("文件格式有误,请检查上传文件格式!!"); } }
2.导入空数据的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实现1)首先要自定义监听器,继承AnalysisEventListener<转换excel的对象>2)实现他的三个方法invoke 逐行解析excel,每一行都会执行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实现导入+各种数据校验的文章就介绍到这了,更多相关EasyExcel导入数据校验内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论