《Excel导入》

前言:

        项目架构:

                       前端框架:Angular6 + ng-zorro-antd

                       后端架构:SSM + Dubbo:springMVC + spring + myBatis-plus
         接下来请跟随小编来看看Excel导入是如何实现的呢?

正文:

                                                                                               前端

    一。效果图

   二。前端交互核心代码

customReq = (item: UploadXHRArgs) => {
    // 构建一个 FormData 对象,用于存储文件或其他参数
    const formData = new FormData();
    // tslint:disable-next-line:no-any
    formData.append('file', item.file as any);
    formData.append('id', '1000');
    const req = new HttpRequest('POST', item.action, formData, {
      reportProgress: true,
      withCredentials: true
    });
    // 始终返回一个 `Subscription` 对象,nz-upload 会在适当时机自动取消订阅
    return this.httpClient.request(req).subscribe((event: HttpEvent<{}>) => {
      console.log('event------', event);
      if (event.type === HttpEventType.UploadProgress) {
        if (event.total > 0) {
          // tslint:disable-next-line:no-any
          (event as any).percent = event.loaded / event.total * 100;
        }
        // 处理上传进度条,必须指定 `percent` 属性来表示进度
        item.onProgress(event, item.file);
      } else if (event instanceof HttpResponse) {
        // 处理成功
        item.onSuccess(event.body, item.file, event);
        const responseBody = JSON.parse(JSON.stringify(event.body));
        console.log('responseBody' + JSON.stringify(responseBody));
        if (responseBody.code === ResponseCode.SUCCESSCODE) {
          this.tipMsgService.createMessage(ResponseCode.SUCCESSTIP, responseBody.message);
        } else if (responseBody.code === ResponseCode.FAILCODE) {
          this.tipMsgService.error('温馨提示', responseBody.message);
        } else if (responseBody.code === ResponseCode.UPLOADCODE) {
          this.tipMsgService.error('温馨提示', '部分导入信息失败,已下载相关错误新信息请查看');
          const errorListId = responseBody.data;
          const url = 'demo-web/foo/exportErrorFooById/' + errorListId;
          const downURL = this.http.getserverUrl(url);
          window.open(downURL);
          URL.revokeObjectURL(downURL);
        }
      }
    }, (err) => {
      // 处理失败
      item.onError(err, item.file);
      this.tipMsgService.error('温馨提示', '抱歉,上传文件失败');
    });
  }

                                                                                             后端

一.pom文件引入核心jar包

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>

 

  二。导入业务逻辑核心代码

public ItooResult importTemplate(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("UTF-8");
        //日期转换字符串的格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        try {
            //校验文件是否存在
            String fileName = multipartFile.getOriginalFilename();
            if (fileName == null) {
                log.error("导入失败,fileName is null");
                return ItooResult.build(ItooResult.FAIL, "传入的文件为空");
            }

            //map<fooGroupName, FooGroupEntity>定义map,方便后续数据存取
            Map<String, FooGroupEntity> fooGroupEntityMap = new HashMap<>(16);

            //Excel解析成list
            Map<Serializable, Serializable> map = new HashMap<>(4);
            map.put(SHEET_NAME, "用户信息");
            map.put(CLASS, FooImportTemplate.class);
            List<FooImportTemplate> fooImportTemplateList = ExcelUtil.importExcel(Objects.requireNonNull(fileName), map, request, response);
            if (fooImportTemplateList.size() == 0) {
                return ItooResult.build(ItooResult.FAIL, "请检查导入的数据");
            }
            //定义导入错误数据集合并存redis中形式<String, FooTemplate>
            List<FooTemplate> errorFooList = new ArrayList<>();
            String errorListId = BaseUuidUtils.base58Uuid();
            Long size = redisTemplate.opsForSet().size(errorListId);
            size = size == null ? 0L : size;
            //循环处理数据
            for (FooImportTemplate excelFoo : fooImportTemplateList) {
                //约束:userCode,userName必填,同时要导入userCode不能与数据库汇总的其他userCode相同
                if (!this.verify(excelFoo)) {
                    FooTemplate fooTemplate = new FooTemplate();
                    BeanUtils.copyProperties(excelFoo, fooTemplate);
                    fooTemplate.setStartTime(simpleDateFormat.format(excelFoo.getStartTime()));
                    errorFooList.add(fooTemplate);
                    redisTemplate.opsForZSet().add(errorListId, fooTemplate, size + 1);
                    continue;
                }
                //判断组是否存在,不存在则查询或创建
                String fooGroupName = excelFoo.getFooGroupName();
                if (fooGroupEntityMap.get(fooGroupName) == null) {
                    //fooGroupName不存在map中,则查询数据库,如果没有则创建
                    FooGroupEntity fooGroupEntity = fooGroupService.findByDeptName(fooGroupName);

                    if (fooGroupEntity == null) {
                        //创建fooGroup,保存到数据库
                        fooGroupEntity = new FooGroupEntity();
                        //todo
                        fooGroupEntity.setId(IdWorker.getIdStr());
                        fooGroupEntity.setParentId("0");
                        fooGroupEntity.setDeptName(fooGroupName);
                        fooGroupService.save(fooGroupEntity);
                    }
                    //将fooGroupEntity放入map中,下次就不用再查询数据库了
                    fooGroupEntityMap.put(fooGroupName, fooGroupEntity);
                }

                //new出FooEntity对象,通过BeanUtils把相同属性进行拷贝,然后处理不能拷贝的特殊属性
                FooEntity fooEntity = new FooEntity();
                BeanUtils.copyProperties(excelFoo, fooEntity);
                fooEntity.setFooGroupId(fooGroupEntityMap.get(fooGroupName).getId());

                //保存到数据库 
                this.save(fooEntity);
            }

            //不符合条件的信息返回
            if (errorFooList.size() > 0){
                return ItooResult.build("0001", "部分导入失败", errorListId);
            }

        } catch (Exception e) {
            return ItooResult.build(ItooResult.FAIL, "导入用户异常");
        }
        return ItooResult.build(ItooResult.SUCCESS, "导入用户成功");
    }

在处理导入的核心业务逻辑中,有两个点需要特殊处理:(1)校验  (2)导入部分失败,此处代码示例做了这两部分的处理:

  2.1 导入文件的数据校验

    private boolean verify(FooImportTemplate fooImportTemplate) {
        //判断非空字段是否有值
        if (StringUtils.isEmpty(fooImportTemplate.getUserCode())) {
            fooImportTemplate.setFailReason("userCode未填写");
            log.warn("导入失败,userCode未填写,excelFooEntity-{}", fooImportTemplate);
        }
        if (StringUtils.isEmpty(fooImportTemplate.getUserName())) {
            fooImportTemplate.setFailReason("userName未填写");
            log.warn("导入失败,userName未填写,excelFooEntity-{}", fooImportTemplate);
        }
        //判断用户名是否重复
        if (fooDao.queryByUserCode(fooImportTemplate.getUserCode()).size() > 0) {
            fooImportTemplate.setFailReason("userCode已存在");
            log.warn("导入失败,userCode已存在,excelFooEntity-{}", fooImportTemplate);
            return false;
        }
        return true;
    }

   2.2 部分导入失败,将信息记录,同时返回给前端,并且在返回的数据中涵盖错误原因

                //约束:userCode,userName必填,同时要导入userCode不能与数据库汇总的其他userCode相同
                if (!this.verify(excelFoo)) {
                    FooTemplate fooTemplate = new FooTemplate();
                    BeanUtils.copyProperties(excelFoo, fooTemplate);
                    fooTemplate.setStartTime(simpleDateFormat.format(excelFoo.getStartTime()));
                    errorFooList.add(fooTemplate);
                    redisTemplate.opsForZSet().add(errorListId, fooTemplate, size + 1);
                    continue;
                }

结语:

              与此篇文章相关的博客:

              《下载excel模板》:https://blog.csdn.net/yxf15732625262/article/details/84639283

               《excel导出》:https://blog.csdn.net/yxf15732625262/article/details/84593696

        

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值