Excel导入与导出

目录

一、读取Excel数据

二、查看Excel上传数据

三、查看数据无误后确认上传

四、导出错误数据


一、读取Excel数据

1、Controller代码

    /**
    * 读取Excel数据
    * file->文件
    * fileId->保存到数据库的唯一标识,用来区别不同批次
    */
    @RequestMapping(value = "/readExcelToDB", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "读取Excel数据,写入数据库")
    @ResponseBody
    public CommonRsp<?> readExcelToDB(@RequestParam("file") MultipartFile file,     @RequestParam("fileId") String fileId) {
        String fileidNew = ruleService.readExcelToDB(file, fileId);
        if (StringUtils.isNotBlank(fileidNew)) {
            return CommonRsp.successSys(fileidNew);
        } else {
            return CommonRsp.errorSys400("500", "上传失败,请联系管理员");
        }
    }

2、Service代码

    @Override
    @Transactional
    public String readExcelToDB(MultipartFile file, String fileId) {
        // 文件id:如果为空,是初始导入;如果非空,是重新导入
        // 是否重新导入
        boolean reUpload = true;
        // 根据oldFileid是否为空确定是导入还是重新导入!!
        if (org.apache.commons.lang.StringUtils.isBlank(fileId) || "null".equals(fileId)) {
            reUpload = false;
            // 初次导入,随机生成文件id
            fileId = UUIDUtil.randomUUID();
        }
        // 文件是否为空校验
        if (file.isEmpty()) {
            UP_STAT.remove(fileId);
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "请选择文件"));
        }
        try {
            Workbook workbook = new XSSFWorkbook(file.getInputStream());
            // 重新定义变量用于新线程(优化部分,暂未使用)
            String finalFileId = fileId;
            boolean finalReUpload = reUpload;
            Workbook finalWorkbook = workbook;
            // 核心代码
            uploadCore(finalFileId, finalReUpload, finalWorkbook);
        } catch (IOException e) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "获取文件失败"));
        } catch (Exception e) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "上传文件异常"));
        }
        return fileId;
    }
    /**
     * 上传文件核心代码
     */
    private void uploadCore(String fileId, boolean reUpload, Workbook workbook) throws Exception {
        // 两种获取sheet页方法
        Sheet ruleSheet = workbook.getSheet("规则维护");
        Sheet ruleSkillSheet = workbook.getSheetAt(2);
        if (ruleSheet == null || ruleSkillSheet == null) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "请勿修改模板"));
        }
        // 获取行数
        int lastRowNum = ruleSheet.getLastRowNum();
        if (lastRowNum < 1) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "没有读取到任何数据"));
        }
        // 将Excel内容读取到资源DO
        List<RuleImportDO> ruleImportDOList = readExcelToImportDO(ruleSheet, lastRowNum);
        if (ruleImportDOList.isEmpty()) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "没有读取到任何数据"));
        }
        // 将Excel内容读取到资源DO
        List<RuleSkillImportDO> ruleSkillImportDOList = readExcelToSkillImportDO(ruleSkillSheet);
        if (ruleSkillImportDOList.isEmpty()) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "没有读取到任何数据"));
        }
        // 各种校验,同时保存数据到临时表
        checkAndSave(ruleImportDOList, ruleSkillImportDOList, fileId, reUpload);
    }
    /**
    *各种校验,同时保存数据到临时表
    */
    private void checkAndSave(List<RuleImportDO> ruleImportDOList, List<RuleSkillImportDO> ruleSkillImportDOList, String fileId, boolean reUpload) {
        //遍历循环规则维护校验数据
        for (RuleImportDO excelVO : ruleImportDOList) {
            excelVO.setFileId(fileId);
            // 异常信息
            StringBuilder exceptionMsg = new StringBuilder();
            // 细节校验(细节校验,略)
            checkRuleSheet(exceptionMsg, excelVO);

            // 有报错信息,属于报错组
            if (!exceptionMsg.toString().equals("")) {
                excelVO.setRowType(3);
                excelVO.setExceptionMsg(exceptionMsg.toString());
                continue;
            }
            // 系统中存在相同规则编号属于修改组,不存在为新增组
            RuleDO ruleDO = ruleService.getOne(new QueryWrapper<RuleDO>().eq("qt_number", excelVO.getQtNumber()));
            if (ruleDO != null) {
                excelVO.setRowType(2);
            } else {
                excelVO.setRowType(1);
            }

        }
        //遍历循环规则脚本维护校验数据
        for (RuleSkillImportDO excelVO : ruleSkillImportDOList) {
            excelVO.setFileId(fileId);
            // 异常信息
            StringBuilder exceptionMsg = new StringBuilder();
            // 细节校验(细节校验,略)
            checkRuleSkillSheet(exceptionMsg, excelVO, ruleSkillImportDOList);
            // 有报错信息,属于报错组
            if (!exceptionMsg.toString().equals("")) {
                excelVO.setRowType(3);
                excelVO.setExceptionMsg(exceptionMsg.toString());
                continue;
            }
            // 区分新增组、修改组、报错组
            setSkillType(excelVO, ruleImportDOList);
        }
        //在规则维护添加脚本报错提示,并把规则维护设置为报错组
        for (RuleSkillImportDO ruleSkillImportDO : ruleSkillImportDOList) {
            for (RuleImportDO ruleImportDO : ruleImportDOList) {
                if (ruleSkillImportDO.getRowType() == 3) {
                    if (ruleSkillImportDO.getQtNumber().equals(ruleImportDO.getQtNumber())) {
                        ruleImportDO.setExceptionMsg(ruleImportDO.getExceptionMsg() + "【数据库类型】为:" + ruleSkillImportDO.getQsDbType() + "的脚本存在错误数据;");
                        ruleImportDO.setRowType(3);
                    }
                }
            }
        }
        // 重新导入删除相同内容
        if (reUpload) {
            deleteCommonData(fileId, ruleImportDOList, ruleSkillImportDOList);
        }
        // 保存第一个sheet数据到t_dg_qa_rule_import
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        RuleImportMapper mapper = session.getMapper(RuleImportMapper.class);
        for (int i = 0; i < ruleImportDOList.size(); i++) {
            mapper.insertRuleOne(ruleImportDOList.get(i));
            commitSession(session, i);
        }
        commitSession(session, 999);
        // 保存第二个sheet数据到t_dg_qa_rule_skill_import
        for (int i = 0; i < ruleSkillImportDOList.size(); i++) {
            mapper.insertRuleSkillOne(ruleSkillImportDOList.get(i));
            commitSession(session, i);
        }
        commitSession(session, 999);
        session.close();
    }

二、查看Excel上传数据

1、Controller代码

    /**
     * 分页读取excel数据
     * @param params
     * @return
     */
    @PostMapping("/excelList")
    @ApiOperation(value = "上传后列表")
    public CommonRsp<?> excelList(@RequestBody Map<String, Object> params) {
        PageResult page = ruleService.readExcelPage(params);
        return CommonRsp.successSys(page);
    }

2、Service代码

    @Override
    public PageResult readExcelPage(Map<String, Object> params) {
        // 参数校验
        String fileId = (String) params.get("fileId");
        if (org.apache.commons.lang.StringUtils.isBlank(fileId)) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "fileId不能为空"));
        }
        Integer rowType = (Integer) params.get("rowType");
        if (rowType != 1 && rowType != 2 && rowType != 3) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, "400", "rowType只能为1,2,3中的一个数字,分别表示新增,修改,报错"));
        }
        // 分页
        Integer pageNum = (Integer) params.get("pageNum");
        Integer pageSize = (Integer) params.get("pageSize");
        // 查询所有数据
        Integer sheetNum = (Integer) params.get("sheetNum");
        if (sheetNum == null) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, "400", "sheetNum必填,且可选值[1,2]"));
        } else if (sheetNum == 1) {
            List<RuleImportDO> ruleImportDOList = ruleImportMapper.selectList(new QueryWrapper<RuleImportDO>().eq("file_id", fileId).eq("row_type", rowType));
            Page<Object> page = new Page<>(pageNum, pageSize, ruleImportDOList.size());
            List<RuleImportDO> pageRule = ruleImportDOList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            if (rowType == 2) {
                // 修改列表需要同时展示修改前后数据(略)
                return PageUtil.convert(page, genCompareRule(pageRule));
            }
            return PageUtil.convert(page, pageRule);
        } else {
            List<RuleSkillImportDO> ruleSkillImportDOList = ruleSkillImportMapper.selectList(new QueryWrapper<RuleSkillImportDO>().eq("file_id", fileId).eq("row_type", rowType));
            Page<Object> page = new Page<>(pageNum, pageSize, ruleSkillImportDOList.size());
            List<RuleSkillImportDO> pageRuleSkill = ruleSkillImportDOList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            if (rowType == 2) {
                // 修改列表需要同时展示修改前后数据(略)
                return PageUtil.convert(page, genCompareRuleSkill(pageRuleSkill));
            }
            return PageUtil.convert(page, pageRuleSkill);
        }
    }

三、查看数据无误后确认上传

1、Controller代码

     /**
     * 确认导入
     * @param fileId
     * @return
     */
    @PostMapping("/importExcelRule")
    @ApiOperation(value = "确认导入")
    public CommonRsp<?> importExcelRule(@RequestParam String fileId) {
        return CommonRsp.successSys(ruleService.importExcelRule(fileId));
    }

2、Service代码

    @Override
    @Transactional
    public Map<String, String> importExcelRule(String fileId) {
        // 响应参数
        Map<String, String> resMap = new HashMap<>();
        resMap.put("type", "1");//1-成功(默认);2-有部分数据异常
        resMap.put("description", "导入成功");// 修改时系统内数据被删除,给出提示,并丢弃要修改规则(默认导入成功)
        resMap.put("fileId", "");// 新增时规则编号重复,将编号更新并存入临时表
        // 判断数据是否为空
        List<RuleImportDO> ruleSaveList = ruleImportMapper.selectList(new QueryWrapper<RuleImportDO>().eq("file_id", fileId).eq("row_type", 1));
        List<RuleImportDO> ruleUpdateList = ruleImportMapper.selectList(new QueryWrapper<RuleImportDO>().eq("file_id", fileId).eq("row_type", 2));
        List<RuleSkillImportDO> ruleSkillSaveList = ruleSkillImportMapper.selectList(new QueryWrapper<RuleSkillImportDO>().eq("file_id", fileId).eq("row_type", 1));
        List<RuleSkillImportDO> ruleSkillUpdateList = ruleSkillImportMapper.selectList(new QueryWrapper<RuleSkillImportDO>().eq("file_id", fileId).eq("row_type", 2));
        if (ruleSaveList == null && ruleUpdateList == null && ruleSkillSaveList == null && ruleSkillUpdateList == null) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, "400", "没有新增或修改任何数据"));
        }
        // 新增
        if (ruleSaveList != null && ruleSkillSaveList != null) {
           // (业务代码)略
        }

        // 修改
        if (ruleUpdateList != null && ruleSkillUpdateList != null) {
           // (业务代码)略
        }
        // 删除临时表新增组和修改组数据
        ruleImportMapper.delete(new QueryWrapper<RuleImportDO>().eq("file_id", fileId).in("row_type", Arrays.asList(1, 2)));
        ruleSkillImportMapper.delete(new QueryWrapper<RuleSkillImportDO>().eq("file_id", fileId).in("row_type", Arrays.asList(1, 2)));
        return resMap;
    }

四、导出错误数据

1、Controller代码

    /**
     * 导出问题数据
     */
    @GetMapping(value = "/exportProblemData")
    @ApiOperation(value = "导出问题数据")
    public void exportProblemData(@RequestParam String fileId, HttpServletResponse response) {
        ruleService.exportProblemData(response, fileId);
    }

2、Service代码

    @Override
    public void exportProblemData(HttpServletResponse resp, String fileId) {
        if (org.apache.commons.lang.StringUtils.isBlank(fileId)) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "fileId不能为空"));
        }
        try {
            InputStream is = new FileInputStream(DOWNLOAD_FILE_PATH_RULE);
            //本地测试
            //InputStream is = new FileInputStream("C:\\Users\\dell\\Desktop\\excel\\模板\\质量规则模板.xlsx");
            OutputStream os = resp.getOutputStream();
            // 查询并将数据设置到Excel中(可能返回txt文件)
            //Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(is));
            //返回xlsx文件
            XSSFWorkbook workbook = new XSSFWorkbook(is);
            //写数据
            setExceptionData(fileId, workbook);
            // 设置Response头
            resp.reset();
            resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            resp.setCharacterEncoding(CHARSET_UTF_8);
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("exceptionData.xlsx", CHARSET_UTF_8));
            //resp.setHeader("Content-Disposition", "attachment;filename=");
            workbook.write(os);
            workbook.close();
        } catch (IOException e) {
            log.error("下载失败,请联系管理员", e);
            throw new BusinessException(CommonRsp.errorSys400(SuccessEnum.SUCCESS.getCode(), "下载失败:" + e.getMessage()));
        }
    }
    private void setExceptionData(String fileId, Workbook workbook) {
        // 查询临时表中的错误数据
        List<RuleImportDO> ruleImportDOList = ruleImportMapper.selectList(new QueryWrapper<RuleImportDO>().eq("file_id", fileId).eq("row_type", 3));
        if (ruleImportDOList.isEmpty()) {
            throw new BusinessException(CommonRsp.errorMsg(HttpStatus.OK, SuccessEnum.SUCCESS.getCode(), "无数据可下载"));
        }
        List<RuleSkillImportDO> ruleSkillImportDOList = ruleSkillImportMapper.selectList(new QueryWrapper<RuleSkillImportDO>().eq("file_id", fileId).eq("row_type", 3));
        // 写入Workbook
        writeRule(workbook, ruleImportDOList);
        writeRuleSkill(workbook, ruleSkillImportDOList);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值