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


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

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

    伪代码:

    1. @PostMapping("/exportPracticeAppr")
    2. public String exportPracticeAppr(HttpServletResponse response, @RequestBody ExportToExcelParamDto paramDto) throws IOException {
    3. //查询数据 ExportToWordByPracticeApprDto为模板中的参数
    4. List practiceApprExport = baseService.practiceApprExport(paramDto);
    5. if (practiceApprExport != null && !practiceApprExport.isEmpty()) {
    6. // 创建一个zip文件,并打开一个ZipOutputStream来写入文件
    7. FileOutputStream fos = new FileOutputStream(paramDto.getActivityName() + "demo.zip");
    8. ZipOutputStream zos = new ZipOutputStream(fos);
    9. try {
    10. //获取word模板文件
    11. InputStream resourceAsStream = TrActivityGroupServiceImpl.class.getClassLoader().getResourceAsStream("word/导出模板.docx");
    12. XWPFDocument doc = new XWPFDocument(Objects.requireNonNull(resourceAsStream));
    13. //循环处理文件
    14. for (ExportToWordByPracticeApprDto apprDto : practiceApprExport) {
    15. Map replaceMap = BeanUtil.beanToMap(apprDto);
    16. Map resultMap = new HashMap<>();
    17. replaceMap.forEach((placeholder, replacement) -> resultMap.put("{{" + placeholder + "}}", replacement));
    18. replacePlaceholders(doc, resultMap);
    19. // 将Word文档保存为临时文件
    20. File tempFile = File.createTempFile("demo", DOCX);
    21. FileOutputStream tempOut = new FileOutputStream(tempFile);
    22. doc.write(tempOut);
    23. tempOut.close();
    24. // 将临时文件添加到zip文件中 表示压缩包中的文件名称 aa.docx
    25. ZipEntry zipEntry = new ZipEntry("aa.docx");
    26. zos.putNextEntry(zipEntry);
    27. FileInputStream fis = new FileInputStream(tempFile);
    28. IOUtils.copy(fis, zos);
    29. fis.close();
    30. zos.closeEntry();
    31. tempFile.delete();
    32. }
    33. // 关闭zip文件输出流
    34. zos.close();
    35. doc.close();
    36. } catch (Exception e) {
    37. logger.error("文件导出错误{}", e.getMessage());
    38. }
    39. }
    40. // 返回zip文件内容
    41. byte[] zipBytes = IOUtils.toByteArray(Files.newInputStream(Paths.get("demo.zip")));
    42. response.reset();
    43. response.setContentType("application/zip");
    44. response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("demo.zip", "UTF-8"));
    45. response.setContentLength(zipBytes.length);
    46. OutputStream out = response.getOutputStream();
    47. out.write(zipBytes);
    48. out.flush();
    49. out.close();
    50. return "redirect:/";
    51. }
    52. private void replacePlaceholders(XWPFDocument document, Map placeholders) throws IOException, InvalidFormatException {
    53. //处理普通word文字 不包含表格
    54. for (XWPFParagraph paragraph : document.getParagraphs()) {
    55. List runs = paragraph.getRuns();
    56. for (XWPFRun run : runs) {
    57. String text = run.getText(0);
    58. if (text != null) {
    59. for (Map.Entry entry : placeholders.entrySet()) {
    60. if (text.contains(entry.getKey())) {
    61. text = text.replace(entry.getKey(), entry.getValue() != null ? (String) entry.getValue() : "");
    62. run.setText(text, 0);
    63. }
    64. }
    65. }
    66. }
    67. }
    68. // 处理替换表格中的占位符
    69. for (XWPFTable table : document.getTables()) {
    70. for (XWPFTableRow row : table.getRows()) {
    71. for (XWPFTableCell cell : row.getTableCells()) {
    72. for (XWPFParagraph paragraph : cell.getParagraphs()) {
    73. List runs = paragraph.getRuns();
    74. for (XWPFRun run : runs) {
    75. String text = run.getText(0);
    76. if (text != null) {
    77. for (Map.Entry entry : placeholders.entrySet()) {
    78. if (text.contains(entry.getKey())) {
    79. //获取、处理图片略
    80. ...
    81. ...
    82. int format = XWPFDocument.PICTURE_TYPE_PNG;
    83. //图片地址
    84. BufferedImage image = ImageIO.read(new URL(value));
    85. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    86. //suffix为图片的后缀 .png
    87. ImageIO.write(image, suffix, outputStream);
    88. byte[] imageBytes = outputStream.toByteArray();
    89. //后两个参数是宽高
    90. run.addPicture(new ByteArrayInputStream(imageBytes), format, fileName, Units.toEMU(80), Units.toEMU(40));
    91. //替换文字 图片和文字如果都展示
    92. text = text.replace(entry.getKey(), entry.getValue() != null ? (String) entry.getValue() : "");
    93. run.setText(text, 0);
    94. }
    95. }
    96. }
    97. }
    98. }
    99. }
    100. }
    101. }
    102. }

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

  • 相关阅读:
    Python分支结构和循环结构
    广州蓝景—11个ES2022(ES13)中惊人的JavaScript新特性
    @RestControllerAdvice 统一异常处理
    【C++杂货铺】探索stack和queue的底层实现
    小程序测试基础知识分享,获取专业测试报告就找卓码软件测评
    where 1=1 是什么意思
    『Java』XStream基础使用与部分源码浅析
    【JAVA-Day15】Java 的 do-while 循环语句
    智慧金融新视野:银行数据中心可视化大屏的崛起
    VuePress的简单使用
  • 原文地址:https://blog.csdn.net/qq_29958413/article/details/134531838