使用 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();
}
}
替换模版中的占位符
在上面的控制器代码中,我们加载了模版文档,准备了一些数据,然后遍历文档中的每个段落,查找并替换占位符。