使用 Spring Boot + POI 实现动态 DOCX 模版导出

使用 Spring Boot + POI 实现动态 DOCX 模版导出

在企业级应用开发中,根据业务逻辑动态生成Word文档(如报告、合同、通知等)的需求十分常见。Apache POI 是一个强大的 Java 库,能读写 Microsoft Office 格式的文件,包括 DOCX。结合 Spring Boot 的特性,可以轻松实现基于模板的动态文档生成。下面是如何使用 Spring Boot 和 Apache POI 创建一个简单的动态 DOCX 模版导出应用的指南。

环境准备

  • Java 11+
  • Spring Boot 2.7.0 或更高版本
  • Maven 或 Gradle 构建工具
  • Apache POI 库

添加依赖

在你的 pom.xml 文件中添加以下依赖:

xml 复制代码
<dependencies> 
  <!-- Spring Boot Web Starter --> 
  <dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
  </dependency> <!-- Apache POI for handling DOCX files --> 
  <dependency> <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml</artifactId> 
    <version>5.2.2</version> 
  </dependency>
</dependencies>

创建模版

在项目的资源目录下创建一个 .docx 文件作为模版。例如,创建一个名为 reportTemplate.docx 的文件,其中包含占位符,如 ${name}${date} 等。

编写控制器

创建一个控制器类,用于处理 HTTP 请求并生成动态文档。

java 复制代码
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map;

@GetMapping(value = "/generateReport", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@RestController public class ReportController {
  public void generateReport(HttpServletResponse response) throws IOException {
      // Load the template document
      XWPFDocument doc = new XWPFDocument(getClass().getResourceAsStream("/templates/reportTemplate.docx"));

      // Prepare data
      Map<String, String> data = new HashMap<>();
      data.put("name", "John Doe");
      data.put("date", "2023-04-01");

      // Replace placeholders with actual data
      for (XWPFParagraph paragraph : doc.getParagraphs()) {
          for (String key : data.keySet()) {
              String text = paragraph.getText();
              if (text.contains(key)) {
                  paragraph.setText(text.replace(key, data.get(key)), 0);
              }
          }
      }

      // Set response headers
      response.setHeader("Content-Disposition", "attachment; filename=generatedReport.docx");
      response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

      // Write the document to the response output stream
      doc.write(response.getOutputStream());
      doc.close();
  }
}

替换模版中的占位符

在上面的控制器代码中,我们加载了模版文档,准备了一些数据,然后遍历文档中的每个段落,查找并替换占位符。

我是失忆,继续在代码江湖中书写属于自己的平凡传奇,更多精彩,敬请关注!
相关推荐
间彧4 分钟前
DateTimeFormatter相比SimpleDateFormat在性能上有何差异?
java
间彧15 分钟前
为什么说SimpleDateFormat是经典的线程不安全类
java
似水流年流不尽思念20 分钟前
MongoDB 有哪些索引?适用场景?
后端·mongodb
MacroZheng22 分钟前
横空出世!MyBatis-Plus 同款 ES ORM 框架,用起来够优雅!
java·后端·elasticsearch
武子康23 分钟前
大数据-100 Spark DStream 转换操作全面总结:map、reduceByKey 到 transform 的实战案例
大数据·后端·spark
bobz96527 分钟前
网段分配
后端
bobz96532 分钟前
VRRP 负载均衡:一个网段多个网关(网关数量和交换机数目一致:一般是两个)
后端
bobz96535 分钟前
VRRP 简记
后端
冯仙笙42 分钟前
统一支付入口集成六种支付方式
后端
无双_Joney1 小时前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs