当前位置:首页 » 《随便一记》 » 正文

EasyExcel实现导入+各种数据校验

1 人参与  2023年04月02日 10:36  分类 : 《随便一记》  评论

点击全文阅读


实现的功能

实现的功能

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 ConfigVO {       @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)自定义监听器

@Slf4jpublic 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) {        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 customerName = 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, 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"));    }    //是否有导入错误的数据    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.lastIndexOf(".") + 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方法中编写

@Overridepublic 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中是否包含我们的表头就可以校验是否是我们提供的模板


点击全文阅读


本文链接:http://zhangshiyu.com/post/57933.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1