easypoi导入、字段校验、ExcelImportUtil.importExcelMore读取文件效率慢问题解决

easyPoi使用遇到的坑

吐槽一下easypoi;最近在公司做一个excel的导入、导出功能,看到之前公司项目中用到了poi技术;为了方便,所以我直接选用了easyPoi来做这个功能,首先在导入maven依赖时没啥问题。在使用的时候,好家伙直接jar包冲突!后来在依赖上加上“-beta1”就好了

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>3.17-beta1</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.17-beta1</version>
</dependency>

这里主要讲下导入字段校验、和读取文件效率的问题

一、字段校验:

在字段校验的时候,可直接在实体类添加注解做字段校验(相关注解可自己百度);然后在ImportParams中设置开启字段校验。

在这里插入图片描述

设置开启字段校验

		ImportParams params = new ImportParams();
        params.setNeedVerfiy(true);//是否开启校验
        params.setHeadRows(1); //头行忽略的行数
        ExcelImportResult<Object> objectExcelImportResult = ExcelImportUtil.importExcelMore(file.getInputStream(), CTourGuide.class, params);
        //校验失败的数据
        objectExcelImportResult.getFailList();
        //校验成功的数据
        objectExcelImportResult.getList();

二、读取效率问题

数据量大的话,ExcelImportUtil.importExcelMore这个方法真的会卡死,不知道是我代码的问题还是api的问题,咱也不敢说,咱也不敢问!在源码中断点看下是在哪卡住的,结果在这。。。
在这里插入图片描述

解决方法:给他里面的一些东西拎出来自己写(不知会不会发生其他问题哈)

	    //直接放到你的controller中
        final ExcelImportService excelImportService = new ExcelImportService();
        ExcelImportResult excelImportResult =excelImportService.importExcelByIs(file.getInputStream(), CTourGuide.class, params, false);
        //校验成功数据
        List<CTourGuide> list = excelImportResult.getList();

        final Field failCollection = ExcelImportService.class.getDeclaredField("failCollection");
        failCollection.setAccessible(true);
        //校验失败数据
        List<CTourGuide> failList = (List) failCollection.get(excelImportService);

批量插入最好是将一个List放到xml中遍历插入,若数据库对一次插入数据量有限制,还需要对list分割处理,再插入。提供下分割代码,xml里面的看下循环标签

    public void addBath(List<CTourGuide> list, int splitSize) {
//        List<CTourGuide> temp = new ArrayList<>();
//        int size = 0;
//        for (CTourGuide cTourGuide : list) {
//            if(++size == splitSize){
//                add(temp);
//                temp.clear();
//                size = 0;
//            }else{
//                temp.add(cTourGuide);
//            }
//        }
//        if(temp.size() != 0){
//            add(temp);
//        }

        int maxSize = (list.size() + splitSize - 1);
        //分割list
        List<List<CTourGuide>> collect = Stream.iterate(0, n -> n + 1)
                .limit(maxSize)
                .parallel()
                .map(a -> list.parallelStream().skip(a * splitSize).limit(splitSize).collect(Collectors.toList()))
                .filter(b -> !b.isEmpty())
                .collect(Collectors.toList());
        if(collect.size()>0){
            for (int i = 0; i < collect.size(); i++) {
                this.add(collect.get(i));
            }
        }

    }

最后提供下我的controller;写的比较烂o(╥﹏╥)o

@RequestMapping("/importMonitor")
    @ResponseBody
    public Map<String, String> importMonitor(@RequestParam MultipartFile file) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        if (file==null){
            map.put("flag","1");
            map.put("msg","导入失败,上传文件数据不能为空");
            return map;
        }

        ImportParams params = new ImportParams();
        params.setNeedVerfiy(true);//是否开启校验
        params.setHeadRows(1); //头行忽略的行数

        final ExcelImportService excelImportService = new ExcelImportService();
        ExcelImportResult excelImportResult =excelImportService.importExcelByIs(file.getInputStream(), CTourGuide.class, params, false);
        //校验成功数据
        List<CTourGuide> list = excelImportResult.getList();

        final Field failCollection = ExcelImportService.class.getDeclaredField("failCollection");
        failCollection.setAccessible(true);
        //校验失败数据
        List<CTourGuide> failList = (List) failCollection.get(excelImportService);

        if(list.size() == 0 && failList.size() == 0){
            map.put("flag","1");
            map.put("msg","导入失败,上传文件数据不能为空");
            return map;
        }

        //失败数据入库
        if (failList.size()>=0){
            failList.stream().forEach(p ->{
                p.setCreateTime(new Date());
                p.setUpdateTime(new Date());
                p.setSfzh(Base64.encode(p.getSfzh()));
                p.setSxstatus(0);
            });
            cTourGuideService.addBath(failList,500);
        }
        //如果没有错误,可以存入数据库
        if(list.size()>=0){
            list.stream().forEach(p ->{
                p.setCreateTime(new Date());
                p.setUpdateTime(new Date());
                p.setSfzh(Base64.encode(p.getSfzh()));
                p.setSxstatus(2);
            });
            cTourGuideService.addBath(list,500);
        }
        map.put("flag","0");
        map.put("msg","导入成功");
        String num = Convert.toStr(failList.size()+list.size());
        map.put("num",num);
        return map;
    }
  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值