Java查询多条数据放入word模板 多个word文件处理成zip压缩包并在前端下载.zip文件

需求:Java查询多条数据放入word模板 多个word文件处理成zip压缩包并在前端下载.zip文件

解决方法:在模板的位置定义参数如 {{name}} {{age}}等等,使用 poi 处理

伪代码:

java 复制代码
    @PostMapping("/exportPracticeAppr")
    public String exportPracticeAppr(HttpServletResponse response, @RequestBody ExportToExcelParamDto paramDto) throws IOException {
        //查询数据 ExportToWordByPracticeApprDto为模板中的参数
        List<ExportToWordByPracticeApprDto> practiceApprExport = baseService.practiceApprExport(paramDto);

        if (practiceApprExport != null && !practiceApprExport.isEmpty()) {
            // 创建一个zip文件,并打开一个ZipOutputStream来写入文件
            FileOutputStream fos = new FileOutputStream(paramDto.getActivityName() + "demo.zip");
            ZipOutputStream zos = new ZipOutputStream(fos);

            try {
                //获取word模板文件
                InputStream resourceAsStream = TrActivityGroupServiceImpl.class.getClassLoader().getResourceAsStream("word/导出模板.docx");
                XWPFDocument doc = new XWPFDocument(Objects.requireNonNull(resourceAsStream));
                //循环处理文件
                for (ExportToWordByPracticeApprDto apprDto : practiceApprExport) {
                    Map<String, Object> replaceMap = BeanUtil.beanToMap(apprDto);
                    Map<String, Object> resultMap = new HashMap<>();
                    replaceMap.forEach((placeholder, replacement) -> resultMap.put("{{" + placeholder + "}}", replacement));
                    replacePlaceholders(doc, resultMap);
                    // 将Word文档保存为临时文件
                    File tempFile = File.createTempFile("demo", DOCX);
                    FileOutputStream tempOut = new FileOutputStream(tempFile);
                    doc.write(tempOut);
                    tempOut.close();

                    // 将临时文件添加到zip文件中  表示压缩包中的文件名称 aa.docx
                    ZipEntry zipEntry = new ZipEntry("aa.docx");
                    zos.putNextEntry(zipEntry);
                    FileInputStream fis = new FileInputStream(tempFile);
                    IOUtils.copy(fis, zos);
                    fis.close();
                    zos.closeEntry();
                    tempFile.delete();
                }

                // 关闭zip文件输出流
                zos.close();
                doc.close();
            } catch (Exception e) {
                logger.error("文件导出错误{}", e.getMessage());
            }
        }

        // 返回zip文件内容
        byte[] zipBytes = IOUtils.toByteArray(Files.newInputStream(Paths.get("demo.zip")));
        response.reset();
        response.setContentType("application/zip");
        response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("demo.zip", "UTF-8"));
        response.setContentLength(zipBytes.length);
        OutputStream out = response.getOutputStream();
        out.write(zipBytes);
        out.flush();
        out.close();
        return "redirect:/";
    }



private void replacePlaceholders(XWPFDocument document, Map<String, Object> placeholders) throws IOException, InvalidFormatException {
        //处理普通word文字 不包含表格
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, Object> entry : placeholders.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            text = text.replace(entry.getKey(), entry.getValue() != null ? (String) entry.getValue() : "");
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }

        // 处理替换表格中的占位符
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            String text = run.getText(0);
                            if (text != null) {
                                for (Map.Entry<String, Object> entry : placeholders.entrySet()) {
                                    if (text.contains(entry.getKey())) {
                                        //获取、处理图片略
                                        ...
                                        ...
                                            int format = XWPFDocument.PICTURE_TYPE_PNG;
                                           //图片地址
                                            BufferedImage image = ImageIO.read(new URL(value));
                                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                            //suffix为图片的后缀 .png
                                            ImageIO.write(image, suffix, outputStream);
                                            byte[] imageBytes = outputStream.toByteArray();
                                            //后两个参数是宽高
                                            run.addPicture(new ByteArrayInputStream(imageBytes), format, fileName, Units.toEMU(80), Units.toEMU(40));
                                         //替换文字  图片和文字如果都展示
                                        text = text.replace(entry.getKey(), entry.getValue() != null ? (String) entry.getValue() : "");
                                        run.setText(text, 0);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

最后前端处理进行下载即可。

相关推荐
ldj20203 分钟前
SpringBoot为什么使用new RuntimeException() 来获取调用栈?
java·spring boot·后端
超龄超能程序猿3 分钟前
Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践
java·spring boot·后端·spring·spring cloud
群联云防护小杜6 分钟前
深度隐匿源IP:高防+群联AI云防护防绕过实战
运维·服务器·前端·网络·人工智能·网络协议·tcp/ip
风象南15 分钟前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山16 分钟前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y40900116 分钟前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao17 分钟前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克16817 分钟前
java常见的jvm内存分析工具
java·jvm·数据库
汉得数字平台24 分钟前
【鲲苍提效】全面洞察用户体验,助力打造高性能前端应用
前端·前端监控
花海如潮淹31 分钟前
前端性能追踪工具:用户体验的毫秒战争
前端·笔记·ux