Excel的导入导出实战

4 篇文章 0 订阅

一、目前excel导入导出大致有三种工具:

  • poi:功能强大
  • easypoi:基于poi的二次封装,支持注解
  • easyexcel:阿里基于poi的二次封装,支持注解,解决大数据量时内存溢出的问题。
    本文主要给出一个项目中直接使用的poi案例,不展开讨论其他内容, 如预了解三种工具课参考下文: 传送门.

二、客户需求:

导入项目开发计划的excel模板:

一级计划:

在这里插入图片描述

二级计划:

在这里插入图片描述

三级计划:

在这里插入图片描述

约束条件:

  1. excel模板有三个sheet:一级计划、二级计划、三级计划;

在这里插入图片描述

  1. 其中一、二、三级计划具有父子关系;

在这里插入图片描述

  1. 单条计划可指派给多个部门,每个模板对应的部门不定;

在这里插入图片描述

  1. 每个部门内的计划明细 具有序号、名称、时间、责任人;

在这里插入图片描述

三、思路

约束一:可通过校验sheet的有无解决
约束二:可校验序号的关系解决(设定三个set集合分别对应一级序号、二级序号、三级序号)
约束三:部门可从特定部位遍历
约束四:时间检验格式、前后时间大小;责任人的检验可将系统用户取出放入set,判断模板上的责任人是否为系统用户

四、代码:(项目中直接粘过来,请酌情修改)

解析序号的时候有时1.1会变成1.10000000001;解决方案请看传送门.

  /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 解析exel
     */
    @Override
    public R poiImportTemplat(MultipartFile file) throws IOException {
        if(file==null){
            return R.fail("文件不可为空!");
        }
        log.info("<--文件获取成功,开始解析-->");
        final String PREFIX = "模板有误:";
        final String ERROR_PREFIX = "导入失败:";
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        Sheet sheet0 = workbook.getSheet("一级计划");
        Sheet sheet1 = workbook.getSheet("二级计划");
        Sheet sheet2 = workbook.getSheet("三级计划");
        if(sheet0==null){
            return R.fail(PREFIX+"未找到一级计划!");
        }
        if(sheet1==null){
            return R.fail(PREFIX+"未找到二级计划!");
        }

        //校验是否存在部门
        Row sheet1row1 = sheet1.getRow(1);
        if(sheet1row1==null||sheet1row1.getPhysicalNumberOfCells()<=8){
            return R.fail(PREFIX+"未找到二级计划的协作部门!");
        }

        // 日期校验、责任人校验 TODO 去重
        //_获取user全集,放入set,用于校验
        Set userSet = new CopyOnWriteArraySet();
        R<List<UserBaseInfoDTO>> listR = iSysUserQueryService.queryAllUserInfo();
        if(listR.getCode()!=200){
            log.info("<--全体用户获取失败-->");
            return R.fail(ERROR_PREFIX+"系统全体用户获取失败!");
        }
        Map<String,UserBaseInfoDTO> userMap = new ConcurrentHashMap();
        if(!listR.getData().isEmpty()){
            listR.getData().stream().forEach(p->userSet.add(p.getUserName()));
            userMap = listR.getData().stream().collect(Collectors.toMap(p -> p.getUserName(), p -> p));
        }else{
            return R.fail(ERROR_PREFIX+"系统全体用户为空,请联系系统管理员完善系统用户!");
        }

        R checkDateUserR1 = this.checkDateUser(sheet0,1,userSet);
        if(checkDateUserR1.getCode()==500){
            return checkDateUserR1;
        }
        R checkDateUserR2 = this.checkDateUser(sheet1,2,userSet);
        if(checkDateUserR2.getCode()==500){
            return checkDateUserR2;
        }
        if(sheet2!=null){
            R checkDateUserR3 = this.checkDateUser(sheet2,3,userSet);
            if(checkDateUserR3.getCode()==500){
                return checkDateUserR3;
            }
        }
        log.info("<--日期、责任人校验通过-->");

        //TODO  data验证
/*        int numberOfCells = sheet0.getRow(0).getPhysicalNumberOfCells();
        if(numberOfCells!=5){
            return R.fail(PREFIX+"一级计划,列数有误!");
        }*/

        /*a.处理模板主信息_获取模板名*/
        String originalFilename = file.getOriginalFilename();
        originalFilename = originalFilename.substring(0,originalFilename.lastIndexOf("."));
        //_模板去重
        Integer existSign = planTemplateMapper.searchTemplateByName(originalFilename);
        if(existSign.intValue()>0){
            return R.fail(ERROR_PREFIX+"同名模板已存在!");
        }
        //创建人信息
        AndawellUser user = AuthUtil.getUser();
        Kv detail = user.getDetail();
        String userId = (String)detail.getObj("sysUserId");
        String userName = (String)detail.getObj("userName");
        List depts = (List)detail.getObj("depts");
        Map o = (Map)depts.get(0);
        String sysOrgId = (String) o.get("sysOrgId");
        String orgName = (String) o.get("orgName");
        String sysDeptId = (String) o.get("sysDeptId");
        String deptName = (String) o.get("deptName");

        //todo  信息完善 & 判重;1模板编号,2创建人信息
        String tempNo = "001";
        PlPlanTemplatePO plPlanTemplatePO = PlPlanTemplatePO.builder()
                .tempNo(tempNo)
                .tempName(originalFilename)
                .tempVersion("V0")
                .tempCreatUserId(userId)
                .tempCreatUserName(userName)
                .tempCreatUserOrgId(sysOrgId)
                .tempCreatUserOrgName(orgName)
                .tempCreatUserDeptId(sysDeptId)
                .tempCreatUserDeptName(deptName)
                .tempCreatTime(new Date())
                .tempStatus("0")
                .build();
        R addTemplateR = this.addTemplateImport(plPlanTemplatePO);
        if(addTemplateR.getCode()==200){
            log.info("<--模板主信息保存成功-->");
        }else{
            log.info("<--模板主信息保存失败-->");
            return R.fail(ERROR_PREFIX+"模板主信息保存失败!");
        }

        /*b.处理模板协作部门_获取模板名_*/
        //存部门(模板id,拿部门名称,选算出来几个)
        R addDeptR = this.addDept(sheet1row1, plPlanTemplatePO.getPlPlanTemplateId());
        List<PlPlanTemplateDeptPO> deptList = new CopyOnWriteArrayList();
        if(addDeptR.getCode()==200){
            log.info("<--模板部门保存成功,开始解析计划-->");
            deptList= (List) addDeptR.getData();
        }else{
            log.info("<--模板部门保存失败-->");
            return R.fail(ERROR_PREFIX+"模板部门保存失败!");
        }


        /*c.拿到模板id、协作部门信息,新增任务信息*/
        //初始化计划(空集合)
        PlanTemplateTaskAddVO planTemplate = new PlanTemplateTaskAddVO();
        //设置计划所属模板
        planTemplate.setPlPlanTemplateId(plPlanTemplatePO.getPlPlanTemplateId());
        //初始化计划明细(空集合)
        planTemplate.setMainTaskList(new CopyOnWriteArrayList<>());

        Set orderNoSet0 = new CopyOnWriteArraySet();//一级计划orderNoSet
        Set orderNoSet1 = new CopyOnWriteArraySet();//二级计划orderNoSet
        Set orderNoSet2 = new CopyOnWriteArraySet();//三级计划orderNoSet
        //TODO 先校验再存,如果在已有的下面,上面的序号存在,维护一个set
        //c.a 解析一级计划
        //todo  一级计划 sheet校验,长度,字段
        //todo 一级计划 校验字段,序号长1.1    pid在,自己不在
        //TODO 10月19 1序号只校验了空,2日期未校验,
        for(int i=2;i<sheet0.getPhysicalNumberOfRows()&&!(sheet0.getRow(i).getCell(0)==null||getValue(sheet0.getRow(i).getCell(0),1)=="");i++){
            String value = getValue(sheet0.getRow(i).getCell(0), 2);
            boolean add = orderNoSet0.add(value);
            if(add){
                //单明细
                PlPlanTemplateDPO planTemplateDetail = PlPlanTemplateDPO.builder()
                        .beginTime(sheet0.getRow(i).getCell(2).getDateCellValue())
                        .overTime(sheet0.getRow(i).getCell(3).getDateCellValue())
                        .build();
                //明细list
                CopyOnWriteArrayList<PlPlanTemplateDPO> detailTaskList = new CopyOnWriteArrayList<>();
                detailTaskList.add(planTemplateDetail);
                //单计划
                PlPlanTemplateListVO planTemplateList = PlPlanTemplateListVO.builder()
                        .plPlanTemplateId(plPlanTemplatePO.getPlPlanTemplateId())
                        .orderNo(value)
                        .taskName(getValue(sheet0.getRow(i).getCell(1),2))
                        .parentId("0")
                        .taskClass("1")
                        .taskDesc(getValue(sheet0.getRow(i).getCell(4),2))
                        .detailTaskList(detailTaskList)
                        .build();
                planTemplate.getMainTaskList().add(planTemplateList);
            }else{
                return R.fail(PREFIX+"一级计划存在重复序号——>"+value);
            }
        }
        log.info("<--一级计划解析成功-->");
        //c.b 解析二级计划
        //todo  一级计划 sheet校验,1长度,2字段对不对 3序号 4pid在, 自己不在
        for(int i=3;i<sheet1.getPhysicalNumberOfRows()&&!(sheet1.getRow(i).getCell(0)==null||getValue(sheet1.getRow(i).getCell(0),1)=="");i++){
            //截取pid,
            String value = getValue(sheet1.getRow(i).getCell(0),2);
            int i1 = value.indexOf(".");
            if(i1==-1){
                boolean add = orderNoSet0.add(value);
                if(add){
                    return R.fail(PREFIX+"二级计划中存在一级计划没有的一级序号——>"+value);
                }
            }else{
                String[] split = value.split("\\.");
                if(split.length>2){
                    return R.fail(PREFIX+"二级计划存在错误序号——>"+value);
                }
                else if(split.length==2){
                    boolean add = orderNoSet0.add(split[0]);
                    if(add){
                        return R.fail(PREFIX+"二级计划存在错误序号——>"+value);
                    }else{
                        boolean ad = orderNoSet1.add(value);
                        if(ad){
                            CopyOnWriteArrayList<PlPlanTemplateDPO> detailTaskList = new CopyOnWriteArrayList<>();
                            int physicalNumberOfCells = sheet1row1.getPhysicalNumberOfCells();
                            for(int j=2,sign=0;j<physicalNumberOfCells;j=j+6,sign++){
                                String stringCellValue1 = getValue(sheet1.getRow(i).getCell(j),2);
                                String stringCellValue2 = getValue(sheet1.getRow(i).getCell(j+1),2);
                                String stringCellValue3 = getValue(sheet1.getRow(i).getCell(j+2),2);
                                String stringCellValue4 = getValue(sheet1.getRow(i).getCell(j+3),2);
                                String stringCellValue5 = getValue(sheet1.getRow(i).getCell(j+4),2);
                                String stringCellValue6 = getValue(sheet1.getRow(i).getCell(j+5),2);
                                boolean stringCellValueSign = !stringCellValue1.isEmpty()
                                        ||!stringCellValue2.isEmpty()
                                        ||!stringCellValue3.isEmpty()
                                        ||!stringCellValue4.isEmpty()
                                        ||!stringCellValue5.isEmpty()
                                        ||!stringCellValue6.isEmpty();
                                if(stringCellValueSign){
                                    //TODO 默认时间对,  责任人对, 信息全集 userMap
                                    String perInchargeName = sheet1.getRow(i).getCell(j + 2).getStringCellValue();
                                    PlPlanTemplateDPO planTemplateDetail = PlPlanTemplateDPO.builder()
                                            .plTeamDeptId(deptList.get(sign).getPlPlanTemplateDeptId())
                                            .beginTime(sheet1.getRow(i).getCell(j).getDateCellValue())
                                            .overTime(sheet1.getRow(i).getCell(j+1).getDateCellValue())
                                            .perInchargeId(userMap.get(perInchargeName).getSysUserId())
                                            .perInchargeName(sheet1.getRow(i).getCell(j+2).getStringCellValue())
                                            .perInchargeDeptId(userMap.get(perInchargeName).getSysDeptId())
                                            .perInchargeDeptName(userMap.get(perInchargeName).getDeptName())
                                            .perInchargeOrgId(userMap.get(perInchargeName).getSysOrgId())
                                            .perInchargeOrgName(userMap.get(perInchargeName).getOrgName())
                                            .inputFile(getValue(sheet1.getRow(i).getCell(j+3),2))
                                            .outputFile(getValue(sheet1.getRow(i).getCell(j+4),2))
                                            .checkStandard(getValue(sheet1.getRow(i).getCell(j+5),2))
                                            .build();
                                    detailTaskList.add(planTemplateDetail);
                                }
                            }
                            PlPlanTemplateListVO planTemplateList = PlPlanTemplateListVO.builder()
                                    .plPlanTemplateId(plPlanTemplatePO.getPlPlanTemplateId())
                                    .orderNo(value)
                                    .taskName(getValue(sheet1.getRow(i).getCell(1),2))
                                    .parentId(split[0])
                                    .taskClass("2")
                                    .detailTaskList(detailTaskList)
                                    .build();
                            planTemplate.getMainTaskList().add(planTemplateList);
                        }else{
                            return R.fail(PREFIX+"二级计划存在重复序号——>"+sheet1.getRow(i).getCell(0).getStringCellValue());
                        }
                    }
                }
            }
        }
        log.info("<--二级计划解析成功-->");
        //c.c 新增三级计划
        if(sheet2!=null){
            //todo  一级计划 sheet校验,1长度,2字段对不对 3序号 4pid在,自己不在
            for(int i=3;i<sheet2.getPhysicalNumberOfRows()&&!(sheet2.getRow(i).getCell(0)==null||getValue(sheet2.getRow(i).getCell(0),1)=="");i++){
                //截取pid,
                String value = getValue(sheet2.getRow(i).getCell(0), 2);
                int i1 = value.indexOf(".");
                if(i1==-1){
                    boolean add = orderNoSet0.add(value);
                    if(add){
                        return R.fail(PREFIX+"三级计划中存在一级计划没有的一级序号——>"+value);
                    }
                }else{
                    String[] split = value.split("\\.");
                    if(split.length==2){
                        boolean add = orderNoSet1.add(value);
                        if(add){
                            return R.fail(PREFIX+"三级计划中存在二级计划没有的二级序号——>"+value);
                        }
                    }
                    else if(split.length==3){
                        //TODO 截取pid
                        int lastIndexOf = value.lastIndexOf(".");
                        String substringPid = value.substring(0, lastIndexOf);
                        boolean add1 = orderNoSet1.add(substringPid); //应false
                        if(add1){
                            return R.fail(PREFIX+"三级计划中存在错误序号——>"+value);
                        }
                        boolean add2 = orderNoSet2.add(value);
                        if(add2){
                            CopyOnWriteArrayList<PlPlanTemplateDPO> detailTaskList = new CopyOnWriteArrayList<>();
                            int physicalNumberOfCells = sheet1row1.getPhysicalNumberOfCells();
                            for(int j=2,sign=0;j<physicalNumberOfCells;j=j+6,sign++){
                                String stringCellValue1 = getValue(sheet2.getRow(i).getCell(j),2);
                                String stringCellValue2 = getValue(sheet2.getRow(i).getCell(j+1),2);
                                String stringCellValue3 = getValue(sheet2.getRow(i).getCell(j+2),2);
                                String stringCellValue4 = getValue(sheet2.getRow(i).getCell(j+3),2);
                                String stringCellValue5 = getValue(sheet2.getRow(i).getCell(j+4),2);
                                String stringCellValue6 = getValue(sheet2.getRow(i).getCell(j+5),2);
                                boolean stringCellValueSign = !stringCellValue1.isEmpty()
                                        ||!stringCellValue2.isEmpty()
                                        ||!stringCellValue3.isEmpty()
                                        ||!stringCellValue4.isEmpty()
                                        ||!stringCellValue5.isEmpty()
                                        ||!stringCellValue6.isEmpty();
                                if(stringCellValueSign){
                                    //TODO 默认时间对,  责任人对
                                    String perInchargeName = sheet1.getRow(i).getCell(j + 2).getStringCellValue();
                                    PlPlanTemplateDPO planTemplateDetail = PlPlanTemplateDPO.builder()
                                            .plTeamDeptId(deptList.get(sign).getPlPlanTemplateDeptId())
                                            .beginTime(sheet2.getRow(i).getCell(j).getDateCellValue())
                                            .overTime(sheet2.getRow(i).getCell(j+1).getDateCellValue())
                                            .perInchargeId(userMap.get(perInchargeName).getSysUserId())
                                            .perInchargeName(sheet1.getRow(i).getCell(j+2).getStringCellValue())
                                            .perInchargeDeptId(userMap.get(perInchargeName).getSysDeptId())
                                            .perInchargeDeptName(userMap.get(perInchargeName).getDeptName())
                                            .perInchargeOrgId(userMap.get(perInchargeName).getSysOrgId())
                                            .perInchargeOrgName(userMap.get(perInchargeName).getOrgName())
                                            .inputFile(sheet2.getRow(i).getCell(j+3).getStringCellValue())
                                            .outputFile(sheet2.getRow(i).getCell(j+4).getStringCellValue())
                                            .checkStandard(sheet2.getRow(i).getCell(j+5).getStringCellValue())
                                            .build();
                                    detailTaskList.add(planTemplateDetail);
                                }
                            }
                            PlPlanTemplateListVO planTemplateList = PlPlanTemplateListVO.builder()
                                    .plPlanTemplateId(plPlanTemplatePO.getPlPlanTemplateId())
                                    .orderNo(value)
                                    .taskName(sheet2.getRow(i).getCell(1).getStringCellValue())
                                    .parentId(substringPid)
                                    .taskClass("3")
                                    .detailTaskList(detailTaskList)
                                    .build();
                            planTemplate.getMainTaskList().add(planTemplateList);
                        }else{
                            return R.fail(PREFIX+"三级计划存在重复序号——>"+value);
                        }
                    }
                    else if(split.length>3){
                        //TODO 截取pid
                        int lastIndexOf = value.lastIndexOf(".");
                        String substringPid = value.substring(0, lastIndexOf);

                        boolean add = orderNoSet2.add(substringPid);//pid应false
                        if(add){
                            return R.fail(PREFIX+"三级计划存在错误序号或错位序号——>"+value);
                        }else{
                            boolean ad = orderNoSet2.add(value);
                            if(ad){
                                CopyOnWriteArrayList<PlPlanTemplateDPO> detailTaskList = new CopyOnWriteArrayList<>();
                                int physicalNumberOfCells = sheet1row1.getPhysicalNumberOfCells();
                                for(int j=2,sign=0;j<physicalNumberOfCells;j=j+6,sign++){
                                    String stringCellValue1 = getValue(sheet2.getRow(i).getCell(j),2);
                                    String stringCellValue2 = getValue(sheet2.getRow(i).getCell(j+1),2);
                                    String stringCellValue3 = getValue(sheet2.getRow(i).getCell(j+2),2);
                                    String stringCellValue4 = getValue(sheet2.getRow(i).getCell(j+3),2);
                                    String stringCellValue5 = getValue(sheet2.getRow(i).getCell(j+4),2);
                                    String stringCellValue6 = getValue(sheet2.getRow(i).getCell(j+5),2);
                                    boolean stringCellValueSign = !stringCellValue1.isEmpty()
                                            ||!stringCellValue2.isEmpty()
                                            ||!stringCellValue3.isEmpty()
                                            ||!stringCellValue4.isEmpty()
                                            ||!stringCellValue5.isEmpty()
                                            ||!stringCellValue6.isEmpty();
                                    if(stringCellValueSign){
                                        //TODO 默认时间对,  责任人对
                                        String perInchargeName = sheet1.getRow(i).getCell(j + 2).getStringCellValue();
                                        PlPlanTemplateDPO planTemplateDetail = PlPlanTemplateDPO.builder()
                                                .plTeamDeptId(deptList.get(sign).getPlPlanTemplateDeptId())
                                                .beginTime(sheet2.getRow(i).getCell(j).getDateCellValue())
                                                .overTime(sheet2.getRow(i).getCell(j+1).getDateCellValue())
                                                .perInchargeId(userMap.get(perInchargeName).getSysUserId())
                                                .perInchargeName(sheet1.getRow(i).getCell(j+2).getStringCellValue())
                                                .perInchargeDeptId(userMap.get(perInchargeName).getSysDeptId())
                                                .perInchargeDeptName(userMap.get(perInchargeName).getDeptName())
                                                .perInchargeOrgId(userMap.get(perInchargeName).getSysOrgId())
                                                .perInchargeOrgName(userMap.get(perInchargeName).getOrgName())
                                                .inputFile(sheet2.getRow(i).getCell(j+3).getStringCellValue())
                                                .outputFile(sheet2.getRow(i).getCell(j+4).getStringCellValue())
                                                .checkStandard(sheet2.getRow(i).getCell(j+5).getStringCellValue())
                                                .build();
                                        detailTaskList.add(planTemplateDetail);
                                    }
                                }
                                PlPlanTemplateListVO planTemplateList = PlPlanTemplateListVO.builder()
                                        .plPlanTemplateId(plPlanTemplatePO.getPlPlanTemplateId())
                                        .orderNo(value)
                                        .taskName(sheet2.getRow(i).getCell(1).getStringCellValue())
                                        .parentId(substringPid)
                                        .taskClass("3")
                                        .detailTaskList(detailTaskList)
                                        .build();
                                planTemplate.getMainTaskList().add(planTemplateList);
                            }else{
                                return R.fail(PREFIX+"三级计划存在重复序号——>"+value);
                            }
                        }
                    }
                }
            }

        }
        log.info("<--三级计划解析成功-->");
        file.getInputStream().close();
        R addTemplateDetailR = this.addTemplateDetail(planTemplate);

        if(addTemplateDetailR.getCode()==200){
            log.info("<--计划信息保存成功,模板导入成功-->");
        }else{
            log.info("<--计划信息保存失败,模板导入失败-->");
            return R.fail(ERROR_PREFIX+"计划信息保存失败!");
        }

        return R.success("校验通过,导入成功!");
    }

    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——校验日期与责任人
     */
    private R checkDateUser(Sheet sheet, int SheetLevel,Set userSet) {
        if(SheetLevel==1){
            Sheet sheet0 = sheet;
            //1.循环校验一级计划
            for(int i=2;i<sheet0.getPhysicalNumberOfRows()&&!(sheet0.getRow(i).getCell(0)==null||getValue(sheet0.getRow(i).getCell(0),1)=="");i++){
                R checkDate = this.checkDate(sheet0.getRow(i).getCell(2),sheet0.getRow(i).getCell(3));
                //1.1如果校验失败
                if(checkDate.getCode()==500){
                    return R.fail("模板有误:一级计划第"+(i-1)+"行"+checkDate.getMsg());
                }
            }
        }else if(SheetLevel==2){
            Sheet sheet1 = sheet;
            //2.循环校验二级计划
            for(int i=3;i<sheet1.getPhysicalNumberOfRows()&&!(sheet1.getRow(i).getCell(0)==null||getValue(sheet1.getRow(i).getCell(0),1)=="");i++){
                int physicalNumberOfCells = sheet1.getRow(1).getPhysicalNumberOfCells();
                //2.1_循环任务详情
                for(int j=2,sign=0;j<physicalNumberOfCells;j=j+6,sign++){
                    //2.2检验日期
                    R checkDate = this.checkDate(sheet1.getRow(i).getCell(j),sheet1.getRow(i).getCell(j + 1));
                    //_2.2.1 如果校验失败
                    if(checkDate.getCode()==500){
                        String row;
                        switch (checkDate.getMsg()) {
                            case "开始时间格式有误": row = "第"+(j+1)+"列";break;
                            case "结束时间格式有误": row = "第"+(j+2)+"列";break;
                            case "结束时间小于开始时间": row = "第"+(j+1)+"列与"+"第"+(j+2)+"列";break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + checkDate.getMsg());
                        }
                        return R.fail("模板有误:二级计划第"+(i-2)+"行,"+row+checkDate.getMsg());
                    }
                    //2.3检验用户
                    R checkUser = this.checkUser(sheet1.getRow(i).getCell(j+2),userSet);
                    if(checkUser.getCode()==500){
                        return R.fail("模板有误:二级计划第"+(i-2)+"行,"+"第"+(j+3)+"列"+checkUser.getMsg());
                    }
                    }

                }
        }else if(SheetLevel==3){
            Sheet sheet2 = sheet;
            //3.循环校验三级计划
            for(int i=3;i<sheet2.getPhysicalNumberOfRows()&&!(sheet2.getRow(i).getCell(0)==null||getValue(sheet2.getRow(i).getCell(0),1)=="");i++){
                int physicalNumberOfCells = sheet2.getRow(1).getPhysicalNumberOfCells();
                //3.1_循环任务详情
                for(int j=2,sign=0;j<physicalNumberOfCells;j=j+6,sign++){
                    R checkDate = this.checkDate(sheet2.getRow(i).getCell(j),sheet2.getRow(i).getCell(j + 1));
                    //3.2 如果校验失败
                    if(checkDate.getCode()==500){
                        String row;
                        switch (checkDate.getMsg()) {
                            case "开始时间格式有误": row = "第"+(j+1)+"列";break;
                            case "结束时间小于开始时间": row = "第"+(j+2)+"列";break;
                            case "结束时间格式有误": row = "第"+(j+1)+"列与"+"第"+(j+2)+"列";break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + checkDate.getMsg());
                        }
                        return R.fail("模板有误:三级计划第"+(i-2)+"行,"+row+checkDate.getMsg());
                    }
                    //3.3检验用户
                    R checkUser = this.checkUser(sheet2.getRow(i).getCell(j+2),userSet);
                    if(checkUser.getCode()==500){
                        return R.fail("模板有误:三级计划第"+(i-2)+"行,"+"第"+(j+3)+"列"+checkUser.getMsg());
                    }
                }
            }
        }
        return R.success("日期与责任人校验成功");
    }


    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——>校验日期与责任人——>校验开始与结束日期
     */
    private R checkDate(Cell cellBefore, Cell cellAfter) {
        final String resultString1 = "开始时间格式有误";
        final String resultString2 = "结束时间格式有误";
        final String resultString3 = "结束时间小于开始时间";
        //1.校验数据是否为空,且为data
        //开始时间,0_非日期类型、1_日期类型
        int signBefore = 0;
        //结束时间,0_非日期类型、1_日期类型
        int afterBefore = 0;
        if(!(cellBefore==null||getValue(cellBefore,2)=="")){
            CellType cellType = cellBefore.getCellType();
            if(cellType==NUMERIC&&DateUtil.isCellDateFormatted(cellBefore)){
                signBefore = 1;
            }else{
                return R.fail(resultString1);
            }
        }
        if(!(cellAfter==null||getValue(cellAfter,2)=="")){
            CellType cellType = cellAfter.getCellType();
            if(cellType==NUMERIC&&DateUtil.isCellDateFormatted(cellAfter)){
                afterBefore = 1;
            }else{
                return R.fail(resultString2);
            }
        }
        //2.检验大小合理性,均存在时启动校验
        if(signBefore==1&&afterBefore==1){
            Date dateBefore = cellBefore.getDateCellValue();
            Date dateAfter = cellAfter.getDateCellValue();
            if(!dateAfter.after(dateBefore)){
                return R.fail(resultString3);
            }
        }
        return R.success("日期校验成功");
    }

    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——>校验日期与责任人——>校验责任人
     */
    private R checkUser(Cell cell,Set userSet) {
        if(!(cell==null||getValue(cell,2)=="")){
            CellType cellType = cell.getCellType();
            if(cellType==STRING){
                String userName = getValue(cell,2);
                if(userSet.add(userName)){
                    return R.fail("责任人不存在");
                }
            }else{
                return R.fail("责任人格式有误");
            }
        }
        return R.success("责任人校验成功");
    }

    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——新增模板信息
     */
    private R addTemplateImport(PlPlanTemplatePO plPlanTemplatePO) {
        //1.校验数据
        if(plPlanTemplatePO.getTempNo() == null || plPlanTemplatePO.getTempNo().isEmpty()){
            return R.fail("模板编号不可为空!");
        }
        String sureTempStatus = "0";
        if(plPlanTemplatePO.getTempStatus() == null || !sureTempStatus.equals(plPlanTemplatePO.getTempStatus())){
            return R.fail("模板状态应为0!");
        }
        //2.新增计划模板主信息
        int sign = planTemplateMapper.insert(plPlanTemplatePO);
        if(sign==1){
            return R.success("计划模板主信息新增成功");
        }else{
            return R.fail("计划模板主信息新增失败");
        }
    }

    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——新增计划模板部门信息
     */
    private R addDept(Row sheet1row1,String plPlanTemplateId) {
        Lock myLock = new ReentrantLock();
        List<PlPlanTemplateDeptPO> deptList = new CopyOnWriteArrayList();
        myLock.lock();
        try {
            int physicalNumberOfCells = sheet1row1.getPhysicalNumberOfCells();
            for(int i=2;i<physicalNumberOfCells;i=i+6){
                Cell cell = sheet1row1.getCell(i);
                //addTemplateDept (模板id,拿部门名称,去到空 或者 选算出来几个)
                PlPlanTemplateDeptPO plPlanTemplateDeptPO = PlPlanTemplateDeptPO.builder()
                        .plPlanTemplateId(plPlanTemplateId)
                        .deptName(cell.getStringCellValue())
                        .build();
                //2.新增计划模板单位信息
                int sign = planTemplateMapper.addTemplateDept(plPlanTemplateDeptPO);
                if(sign!=1){
                    return R.fail("新增计划模板单位信息失败");
                }
                deptList.add(plPlanTemplateDeptPO);
            }
        }  finally {
            myLock.unlock();
        }
        return R.data(deptList,"新增计划模板单位信息成功");
    }



    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——获取cell值
     */
    public String getValue(Cell cell,int type){
        //匹配类型数据
        if (cell != null) {
            CellType cellType = cell.getCellType();
            String cellValue = "";
            switch (cellType) {
                case STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case BLANK:
                    break;
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        cellValue = new DateTime(date).toString("yyyy-MM-dd");
                    } else {
                        //1,校验;2获取值
                        if(type==1){
                            cellValue = cell.toString();
                        }else if(type==2){
                            //不是日期格式,[转换为字符串输出]
                            String cellstr = cell.toString();
                            cell.setCellType(CellType.STRING);
                            cellValue = cell.getStringCellValue();
                            if(cellValue.indexOf(".") > -1) {
                                cellValue = cellstr;
                            }
                        }

                    }
                    break;
                case ERROR:
                    System.out.print("[数据类型错误]");
                    break;
            }
            return cellValue;
        }else{
            return "";
        }
    }

五、PoiUtil工具类:

package com.andawell.ipd.platform.plan.infrastructure.util;

import cn.hutool.core.date.DateTime;
import com.andawell.technology.platform.tools.api.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.apache.poi.ss.usermodel.CellType.*;

/**
 * @author:songwl
 * @Date:2021/11/3 10:47
 * @Description: poi相关的方法
 */
@Component
@SuppressWarnings("all")
@Slf4j
public class PoiUtil {
    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——校验日期与责任人
     * 参数:
     * Sheet sheet       要检验的sheet
     * int SheetLevel    要检验的sheet等级 1一级计划,2二级计划,3三级计划
     * Set userSet       系统全体用户名称
     */
    public R checkDateUser(Sheet sheet, int SheetLevel, Set userSet) {
        if(SheetLevel==1){
            Sheet sheet0 = sheet;
            //1.循环校验一级计划
            for(int i=2;i<sheet0.getPhysicalNumberOfRows()&&sheet0.getRow(i)!=null&&!(sheet0.getRow(i).getCell(0)==null||getValue(sheet0.getRow(i).getCell(0),1)=="");i++){
                R checkDate = this.checkDate(sheet0.getRow(i).getCell(2),sheet0.getRow(i).getCell(3));
                //1.1如果校验失败
                if(checkDate.getCode()==500){
                    return R.fail("模板有误:一级计划第"+(i+1)+"行"+checkDate.getMsg());
                }
            }
        }else if(SheetLevel==2){
            Sheet sheet1 = sheet;
            //2.循环校验二级计划
            for(int i=3;i<sheet1.getPhysicalNumberOfRows()&&sheet1.getRow(i)!=null&&!(sheet1.getRow(i).getCell(0)==null||getValue(sheet1.getRow(i).getCell(0),1)=="");i++){
                int physicalNumberOfCells = sheet1.getRow(2).getPhysicalNumberOfCells();
                //2.1_循环任务详情
                for(int j=2,sign=0;j+4<physicalNumberOfCells;j=j+6,sign++){
                    //2.2检验日期
                    R checkDate = this.checkDate(sheet1.getRow(i).getCell(j),sheet1.getRow(i).getCell(j + 1));
                    //_2.2.1 如果校验失败
                    if(checkDate.getCode()==500){
                        String row;
                        switch (checkDate.getMsg()) {
                            case "开始时间格式有误": row = "第"+getExcelColumn(j+1)+"列";break;
                            case "结束时间格式有误": row = "第"+getExcelColumn(j+2)+"列";break;
                            case "结束时间小于开始时间": row = "第"+getExcelColumn(j+1)+"列与"+"第"+getExcelColumn(j+2)+"列";break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + checkDate.getMsg());
                        }
                        return R.fail("模板有误:二级计划第"+(i+1)+"行,"+row+checkDate.getMsg());
                    }
                    //2.3检验用户  20220228去除用户检验,注释掉
/*                    R checkUser = this.checkUser(sheet1.getRow(i).getCell(j+2),userSet);
                    if(checkUser.getCode()==500){
                        return R.fail("模板有误:二级计划第"+(i+1)+"行,"+"第"+getExcelColumn(j+3)+"列"+checkUser.getMsg());
                    }*/
                }

            }
        }else if(SheetLevel==3){
            Sheet sheet2 = sheet;
            //3.循环校验三级计划
            for(int i=3;i<sheet2.getPhysicalNumberOfRows()&&sheet2.getRow(i)!=null&&!(sheet2.getRow(i).getCell(0)==null||getValue(sheet2.getRow(i).getCell(0),1)=="");i++){
                int physicalNumberOfCells = sheet2.getRow(2).getPhysicalNumberOfCells();
                //3.1_循环任务详情
                for(int j=2,sign=0;j+4<physicalNumberOfCells;j=j+6,sign++){
                    R checkDate = this.checkDate(sheet2.getRow(i).getCell(j),sheet2.getRow(i).getCell(j + 1));
                    //3.2 如果校验失败
                    if(checkDate.getCode()==500){
                        String row;
                        switch (checkDate.getMsg()) {
                            case "开始时间格式有误": row = "第"+getExcelColumn(j+1)+"列";break;
                            case "结束时间小于开始时间": row = "第"+getExcelColumn(j+2)+"列";break;
                            case "结束时间格式有误": row = "第"+getExcelColumn(j+1)+"列与"+"第"+getExcelColumn(j+2)+"列";break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + checkDate.getMsg());
                        }
                        return R.fail("模板有误:三级计划第"+(i+1)+"行,"+row+checkDate.getMsg());
                    }
                    //3.3检验用户 20220228去除用户检验,注释掉
/*                    R checkUser = this.checkUser(sheet2.getRow(i).getCell(j+2),userSet);
                    if(checkUser.getCode()==500){
                        return R.fail("模板有误:三级计划第"+(i+1)+"行,"+"第"+getExcelColumn(j+3)+"列"+checkUser.getMsg());
                    }*/
                }
            }
        }
        return R.success("日期校验成功");
    }


    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——>校验日期与责任人——>校验开始与结束日期
     * 参数:
     * Cell cellBefore   开始时间单元格
     * Cell cellAfter    结束时间单元格
     */
    public R checkDate(Cell cellBefore, Cell cellAfter) {
        final String resultString1 = "开始时间格式有误";
        final String resultString2 = "结束时间格式有误";
        final String resultString3 = "结束时间小于开始时间";
        //1.校验数据是否为空,且为data
        //开始时间,0_非日期类型、1_日期类型
        int signBefore = 0;
        //结束时间,0_非日期类型、1_日期类型
        int afterBefore = 0;
        if(!(cellBefore==null||getValue(cellBefore,2)=="")){
            CellType cellType = cellBefore.getCellType();
            //20230504兼容公式,日期校验添加FORMULA类型的判断
            if(cellType==FORMULA){
                cellType = cellBefore.getCachedFormulaResultType();
            }
            if(cellType==NUMERIC && DateUtil.isCellDateFormatted(cellBefore)){
                signBefore = 1;
            }else{
                return R.fail(resultString1);
            }
        }
        if(!(cellAfter==null||getValue(cellAfter,2)=="")){
            CellType cellType = cellAfter.getCellType();
            //20230504兼容公式,日期校验添加FORMULA类型的判断
            if(cellType==FORMULA){
                cellType = cellBefore.getCachedFormulaResultType();
            }
            if(cellType==NUMERIC && DateUtil.isCellDateFormatted(cellAfter)){
                afterBefore = 1;
            }else{
                return R.fail(resultString2);
            }
        }
        //2.检验大小合理性,均存在时启动校验
        if(signBefore==1&&afterBefore==1){
            Date dateBefore = cellBefore.getDateCellValue();
            Date dateAfter = cellAfter.getDateCellValue();
            if(dateAfter.before(dateBefore)){
                return R.fail(resultString3);
            }
        }
        return R.success("日期校验成功");
    }

    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——>校验日期与责任人——>校验责任人
     * 参数:
     * Cell cell   要校验的责任人单元格
     * Set userSet 系统全体用户名称
     */
    private R checkUser(Cell cell,Set userSet) {
        if(!(cell==null||getValue(cell,2)=="")){
            CellType cellType = cell.getCellType();
            if(cellType==STRING){
                String userName = getValue(cell,2);
                if(userSet.add(userName)){
                    return R.fail("责任人不存在或此用户无效");
                }
            }else{
                return R.fail("责任人格式有误");
            }
        }
        return R.success("责任人校验成功");
    }


    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——获取cell值
     * 参数:
     * Cell cell 单元格;
     * int type 1,校验(检验单元格是否为空);2获取单元格值
     */
    public String getValue(Cell cell,int type){
        //匹配类型数据
        if (cell != null) {
            CellType cellType = cell.getCellType();
            String cellValue = "";
            switch (cellType) {
                case STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case BLANK:
                    break;
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        cellValue = new DateTime(date).toString("yyyy-MM-dd");
                    } else {
                        //1,校验;2获取值
                        if(type==1){
                            cellValue = cell.toString();
                        }else if(type==2){
                            //不是日期格式,[转换为字符串输出]
                            String cellstr = cell.toString();
                            cell.setCellType(CellType.STRING);
                            cellValue = cell.getStringCellValue();
                            if(cellValue.indexOf(".") > -1) {
                                cellValue = cellstr;
                            }
                        }
                    }
                    break;
                case FORMULA:
                    try {
                        CellType resultType = cell.getCachedFormulaResultType();
                        return getFormulaValue(resultType, cell, type);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                        return String.valueOf(cell.getRichStringCellValue());
                    }
                case ERROR:
                    System.out.print("[数据类型错误]");
                    break;
            }
            return cellValue;
        }else{
            return "";
        }
    }


    /**
     * @author: songwl
     * @Date: 2023/4/28 15:12
     * @description: 获取cell为公式时的值
     */
    public String getFormulaValue(CellType resultType,Cell cell,int type){
        //匹配类型数据
        if (cell != null) {
            String cellValue = "";
            switch (resultType) {
                case STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case BLANK:
                    break;
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        cellValue = new DateTime(date).toString("yyyy-MM-dd");
                    } else {
                        //1,校验;2获取值
                        if(type==1){
                            cellValue = cell.toString();
                        }else if(type==2){
                            //不是日期格式,[转换为字符串输出]
                            String cellstr = cell.toString();
                            cell.setCellType(CellType.STRING);
                            cellValue = cell.getStringCellValue();
                            if(cellValue.indexOf(".") > -1) {
                                cellValue = cellstr;
                            }
                        }
                    }
                    break;
                case ERROR:
                    System.out.print("[数据类型错误]");
                    break;
            }
            return cellValue;
        }else{
            return "";
        }
    }


    /**
     * @author: songwl
     * @Date: 2021/10/19 20:59
     * @description: 模板导入——获取cell的Date值
     * 参数:
     * Cell cell 单元格;
     */
    public Date getDateValue(Cell cell){
        //能走到这的Date要么是Date类型要么是""
        try {
            if(cell==null){
                return null;
            }else{
                return cell.getDateCellValue();
            }
        } catch (IllegalStateException e) {
           log.debug("空时间");
           return null;
        }
    }

    //根据excel数字列号获取对应的字母列(excel数字列号从一开始的)
    public  String getExcelColumn(int num){
        String excelColumn = "";
        do{
            int i = num % 26;
            String s = numToCharforAscii(i + 64);
            if(s.equals("overAsciiError")){
                return "overAsciiError";
            }else if(s.equals("overCapitalAsciiError")){
                return "overCapitalAsciiError";
            }else{
                excelColumn = s.concat(excelColumn);
                num = num / 26;
            }
        } while (num!=0);
        return excelColumn;
    }



    //数字获取对应的ascii码
    public  String numToCharforAscii(int num){
        String stringAscii = "";
        if(num<0||num>127){
            return "overAsciiError";
        }else if(num<65||num>90){
            return "overCapitalAsciiError";
        }else{
            char theAscii = (char)num;
            stringAscii = String.valueOf(theAscii);
        }
        return stringAscii;
    }
    

/*    public static void main(String[] args) {
        char theAscii1 = (char)65;
        char theAscii2 = (char)66;
        String s = theAscii1 + theAscii2 + "";
        byte a = (byte) 'A';
        String stringAscii = String.valueOf(theAscii1);
        int i = 28 % 26;

        int i2 = 28/26;

        //String excelColumn = getExcelColumn(40);
    }*/

    /**
     * @author: songwl
     * @Date: 2022/2/28 14:55
     * @description:  0、1转N、Y
     */
    public String changeYn(String args) {
        if("".equals(args)){
            return "";
        }else if("0".equals(args)){
            return "N";
        }else if("1".equals(args)){
            return "Y";
        }else{
            //异常数据
            return "";
        }
    }


    /*********************word***********************/
    //word替换text
    /**
     * @author: songwl
     * @Date: 2022/7/6 16:25
     * @description:  那个cell,那个Paragraphs(默认0),text要替换的内容
     */
/*    public static void replaceParagraphText(XWPFTableCell xwpfTableCell, int i, String aa) {
        XWPFParagraph paragraph = new XWPFParagraph();
        xwpfTableCell.removeParagraph();

              XWPFParagraph paragraph = document.createParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText("666");
    }*/



}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值