记录下用easyexcel怎么读取表格中的图片资源


    @ApiOperation(value = "导入合伙人数据", notes = "从Excel导入合伙人数据")
    @PostMapping("/import")
    public ResultResponse<Map<String, Object>> importIssue(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return ResultResponse.fail("上传文件不能为空");
        }

        // 文件类型校验
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) {
            return ResultResponse.fail("只支持.xls和.xlsx格式的文件");
        }

        // 处理解析结果
        ExcelResult<DistributionApplyExcelDTO> excelResult =
            ExcelUtil.importExcel(file.getInputStream(), DistributionApplyExcelDTO.class, new ExportDemoListener());

        try {
            ZipSecureFile.setMinInflateRatio(-1.0d);
            OPCPackage opcPackage = OPCPackage.open(file.getInputStream());
            XSSFWorkbook book = new XSSFWorkbook(opcPackage);
            // 方式2 获取sheet数量,直接遍历读取每个工作表数据
            for (Sheet sheet : book) {
                XSSFSheet xssSheet = (XSSFSheet) sheet;
                // 获取工作表中绘图包
                XSSFDrawing drawing = xssSheet.getDrawingPatriarch();
                if (drawing == null) {
                    break;
                }
                // 获取所有图像形状
                List<XSSFShape> shapes = drawing.getShapes();
                // 遍历所有形状
                for (XSSFShape shape : shapes) {
                    // 获取形状在工作表中的顶点位置信息(anchor锚点)
                    XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor();
                    // 图片形状在工作表中的位置, 所在行列起点和终点位置
                    short c1 = anchor.getCol1();
                    int r1 = anchor.getRow1();
                    String key = r1 + "行," + c1 + "列";
                    if (shape instanceof XSSFPicture) {
                        try {
                            XSSFPicture pic = (XSSFPicture) shape;
                            // 形状获取对应的图片数据
                            XSSFPictureData picData = pic.getPictureData();
                            // 保存图片到本地
                            byte[] data = picData.getData();
                            // TODO 这里上传文件至oss并生成链接,这里不做过多描述,有疑问请参照oss服务调用
                            // 创建MockMultipartFile对象,直接使用图片字节数组
                            String fileName = "image_" + UUID.randomUUID() + "." + picData.suggestFileExtension();
                            String contentType = picData.suggestFileExtension().equals("jpg") ? "image/jpeg" : "image/png"; // 根据文件扩展名确定内容类型
                            // MockMultipartFile multipartFile = new MockMultipartFile("file", "text/plain" + picData.suggestFileExtension(), contentType, data);
                            MockMultipartFile multipartFile = new MockMultipartFile("file", fileName, contentType, data);
                            SysFile sysFile = remoteFileService.upload(fileName, multipartFile.getOriginalFilename(),
                                multipartFile.getContentType(), multipartFile.getBytes());
                            if (ObjectUtil.isNull(sysFile)) {
                                return ResultResponse.fail("文件服务异常,请联系管理员");
                            }
                            // TODO 放入excel集合,这里行数要减去1,获取图片是从表头开始(表头位置为0),获取excelVos是从数据开始(第一条数据位置为0)他们相差一个表头,所以要减去1才能对应
                            if (c1 == 6) {
                                excelResult.getList().get(r1 - 1).setFrontIdCard(sysFile.getUrl());
                            }
                            if (c1 == 7) {
                                excelResult.getList().get(r1 - 1).setBackIdCard(sysFile.getUrl());
                            }

                        } catch (Exception e) {
                            log.error("asyncImportList XSSFClientAnchor key|{} error|{}", key, e.getMessage());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("asyncImportList XSSFWorkbook error|{}", e.getMessage());
        }


        // 调用服务层方法进行导入
        Map<String, Object> result = distributionService.importDistributionFromExcel(excelResult.getList());
        if (StringUtils.isNotBlank(result.get("failMsg").toString())) {
            throw new ServiceException(result.get("failMsg").toString());
        }
        return ResultResponse.success(result);
    }


    @ApiOperation(value = "下载合伙人导入模板", notes = "下载Excel格式的合伙人导入模板")
    @PostMapping("/import/template")
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("合伙人导入模板", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 创建一个空的模板数据列表
            List<DistributionApplyExcelDTO> templateList = new ArrayList<>();


            List<BankSupportVo> bankSupportVos = getBankSupportList();
            int areaIndex = 5;

            List<DistributionLevelConfig> distributionLevelList = getDistributionLevelList();
            int distributionLeveIndex = 8;

            // 如果传递了字典名,则依据字典建立下拉
            Collection<String> values = Optional.ofNullable(bankSupportVos)
                .orElseThrow(() -> new ServiceException(String.format("开户行不存在")))
                .stream().map(BankSupportVo::getBankName).collect(Collectors.toList());
            List<String> optionsTemp = new ArrayList<>(values);

            DropDownOptions cityToArea = new DropDownOptions(areaIndex, optionsTemp);

            // 如果传递了字典名,则依据字典建立下拉
            Collection<String> values2 = Optional.ofNullable(distributionLevelList)
                .orElseThrow(() -> new ServiceException(String.format("合伙人等级配置不存在")))
                .stream().map(everyOptions -> {
                    // 通过 DropDownOptions.createOptionValue 来构建 OptionValue
                    return DropDownOptions.createOptionValue(everyOptions.getLevelName(), everyOptions.getLevel());
                }).collect(Collectors.toList());
            List<String> optionsTemp2 = new ArrayList<>(values2);

            DropDownOptions cityToArea2 = new DropDownOptions(distributionLeveIndex, optionsTemp2);

            // 把所有的下拉框存储
            List<DropDownOptions> options = new ArrayList<>();
            options.add(cityToArea);
            options.add(cityToArea2);

            // 接下来需要将Excel中的展示数据转换为对应的下拉选
            List<DistributionApplyExcelDTO> outList = StreamUtils.toList(templateList, everyRowData -> {
                // 只需要处理没有使用@ExcelDictFormat注解的下拉框
                // 一般来说,可以直接在数据库查询即查询出省市县信息,这里通过模拟操作赋值
                everyRowData.setSettlementBankBranchName(buildOptions(bankSupportVos, everyRowData.getSettlementBankBranchId()));
                everyRowData.setBrokerageLevelName(buildOptions2(distributionLevelList, everyRowData.getBrokerageLevel()));
                return everyRowData;
            });

            // 使用EasyExcel写入响应流
            ExcelUtil.exportExcel(outList, "合伙人数据", DistributionApplyExcelDTO.class, response, options);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("下载模板异常", e);
            // 重置响应
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().println(JSON.toJSONString(ResultResponse.fail("下载模板失败:" + e.getMessage())));
        }
    }

0

版权声明 ▶ 本网站名称:我的学习笔记
▶ 本文链接:https://ooolo.net/article/633.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!!

none
最后修改于:2025年07月24日 13:13

添加新评论

icon_mrgreen.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_confused.pngicon_cool.pngicon_evil.pngicon_biggrin.pngicon_idea.pngicon_redface.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_surprised.pngicon_lol.pngicon_mad.pngicon_sad.pngicon_exclaim.pngicon_question.png