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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

相关推荐
五月君_5 小时前
炸裂!Claude Opus 4.6 与 GPT-5.3 同日发布:前端人的“自动驾驶“时刻到了?
前端·gpt
Mr Xu_5 小时前
前端开发中CSS代码的优化与复用:从公共样式提取到CSS变量的最佳实践
前端·css
亓才孓5 小时前
[JDBC]批处理
java
春日见5 小时前
车辆动力学:前后轮车轴
java·开发语言·驱动开发·docker·计算机外设
宋小黑5 小时前
JDK 6到25 全版本网盘合集 (Windows + Mac + Linux)
java·后端
鹏北海-RemHusband5 小时前
从零到一:基于 micro-app 的企业级微前端模板完整实现指南
前端·微服务·架构
LYFlied5 小时前
AI大时代下前端跨端解决方案的现状与演进路径
前端·人工智能
光影少年5 小时前
AI 前端 / 高级前端
前端·人工智能·状态模式
7哥♡ۣۖᝰꫛꫀꪝۣℋ6 小时前
Spring-cloud\Eureka
java·spring·微服务·eureka
一位搞嵌入式的 genius6 小时前
深入 JavaScript 函数式编程:从基础到实战(含面试题解析)
前端·javascript·函数式