1. 添加 Maven 依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
2. 构建替换词和对应值Map (根据自己的业务将替换词value改成想要替换的数据)
Map<String, String> replacements = new HashMap<>();
replacements.put("${AA}",city);
replacements.put("${AB}",country);
3. 获取模板文件有两种方式:
a. 放在项目中的resources目录下。
注意需要在pom文件内加上maven-resources-plugin
插件。因为在项目运行编译的过程中,需要忽略掉模板文件,避免编译过程中将文件损坏;并且指定你的文件类型(xls或者是doc等等)。
<!--过滤掉模板文件避免编译损坏-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>doc</nonFilteredFileExtension>
<nonFilteredFileExtension>docx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
// 文件路径相对于 resources 目录
String filePath = "muban/muban.docx";
// 使用类加载器获取资源文件的输入流
InputStream inputStream = new ClassPathResource(filePath).getInputStream();
XWPFDocument document = new XWPFDocument(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream())
b.放在本地磁盘。
本地磁盘不需要设置文件过滤
// 读取 Word 模板文件
FileInputStream fis = new FileInputStream("D:\template.docx");
XWPFDocument document = new XWPFDocument(fis);
4. 遍历文档段落和表格,替换占位符并写入响应:
//构建response流
private static void buildResponse(HttpServletResponse response, Map<String, String> replacements) {
// 文件路径相对于 resources 目录
String filePath = "muban/muban.docx";
// 使用类加载器获取资源文件的输入流
try (InputStream inputStream = new ClassPathResource(filePath).getInputStream();
XWPFDocument document = new XWPFDocument(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
// 遍历段落并进行替换
for (XWPFParagraph paragraph : document.getParagraphs()) {
replaceInParagraph(paragraph, replacements);
}
// 替换表格中的占位符
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
replaceInParagraph(paragraph, replacements);
}
}
}
}
// 将文档写入字节数组输出流
document.write(byteArrayOutputStream);
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setHeader("Content-Disposition", "attachment; filename=xx.docx");
response.setContentLength(byteArrayOutputStream.size());
// 将字节数组输出流的内容写入响应
response.getOutputStream().write(byteArrayOutputStream.toByteArray());
response.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void replaceInParagraph(XWPFParagraph paragraph, Map<String, String> replacements) {
StringBuilder text = new StringBuilder();
for (XWPFRun run : paragraph.getRuns()) {
text.append(run.getText(0));
}
String updatedText = text.toString();
for (Map.Entry<String, String> entry : replacements.entrySet()) {
updatedText = updatedText.replace(entry.getKey(), entry.getValue());
}
// 删除旧的 runs
int size = paragraph.getRuns().size();
for (int i = 0; i < size; i++) {
paragraph.removeRun(0);
}
// 创建新的 run 并设置替换后的文本
XWPFRun newRun = paragraph.createRun();
newRun.setText(updatedText);
}