本文目录导读:

我来详细介绍如何使用poi-tl(Word模板引擎)来填充Word文档。
poi-tl 简介
poi-tl是一个基于Apache POI的Word模板引擎,通过模板标签实现Word文档的动态填充。
添加依赖
Maven
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.1</version>
</dependency>
Gradle
implementation 'com.deepoove:poi-tl:1.12.1'
Word模板准备
在Word文档中使用标签语法:
基本标签
- {{@image}} # 图片
- {{#table}} # 表格
- {{[text]}} # 循环块
模板示例
# 项目报告
项目名称:{{projectName}}
日期:{{date}}
{{description}}
## 成员列表
{{#members}}
姓名:{{name}},角色:{{role}},邮箱:{{email}}
{{/members}}
## 项目图片
{{@projectImage}}
## 数据统计
{{#statistics}}
| 指标 | 数值 |
|------|------|
| {{index}} | {{value}} |
{{/statistics}}
基本用法示例
1 简单文本填充
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.Tables;
import java.util.HashMap;
import java.util.Map;
import java.io.FileOutputStream;
public class WordFiller {
public static void fillSimpleText() throws Exception {
// 准备数据
Map<String, Object> data = new HashMap<>();
data.put("title", "项目进度报告");
data.put("date", "2024-01-15");
data.put("description", "这是一个示例项目描述...");
// 渲染模板
XWPFTemplate template = XWPFTemplate.compile("template.docx")
.render(data);
// 输出到文件
template.writeAndClose(new FileOutputStream("output.docx"));
}
}
2 复杂数据填充
public class ComplexExample {
public static void fillComplexDocument() throws Exception {
// 准备数据模型
Map<String, Object> data = new HashMap<>();
// 文本
data.put("title", "项目报告");
data.put("company", "ABC科技有限公司");
// 列表数据
List<Map<String, Object>> members = new ArrayList<>();
Map<String, Object> member1 = new HashMap<>();
member1.put("name", "张三");
member1.put("role", "项目经理");
member1.put("email", "zhangsan@example.com");
members.add(member1);
Map<String, Object> member2 = new HashMap<>();
member2.put("name", "李四");
member2.put("role", "开发工程师");
member2.put("email", "lisi@example.com");
members.add(member2);
data.put("members", members);
// 图片
data.put("projectImage", Pictures.ofLocal("chart.png")
.size(500, 300)
.create());
// 表格数据
List<Map<String, Object>> statistics = new ArrayList<>();
Map<String, Object> stat1 = new HashMap<>();
stat1.put("index", "完成度");
stat1.put("value", "75%");
statistics.add(stat1);
Map<String, Object> stat2 = new HashMap<>();
stat2.put("index", "代码行数");
stat2.put("value", "15,000");
statistics.add(stat2);
data.put("statistics", statistics);
// 渲染模板
XWPFTemplate template = XWPFTemplate.compile("template.docx")
.render(data);
template.writeAndClose(new FileOutputStream("output.docx"));
}
}
高级功能
1 使用数据模型类
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
// 定义数据模型
public class ReportData {
private String title;
private String date;
private List<Member> members;
private PictureRenderData chart;
private TableRenderData tableData;
// getters and setters
}
public class Member {
private String name;
private String role;
private String email;
// getters and setters
}
// 使用数据模型
public class ModelExample {
public static void fillWithModel() throws Exception {
ReportData reportData = new ReportData();
reportData.setTitle("项目报告");
// ... 设置其他属性
XWPFTemplate template = XWPFTemplate.compile("template.docx")
.render(reportData);
template.writeAndClose(new FileOutputStream("output.docx"));
}
}
2 表格高级操作
import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.TextRenderData;
public class TableExample {
public static void createComplexTable() {
// 创建表头
RowRenderData header = RowRenderData.build(
new TextRenderData("姓名"),
new TextRenderData("年龄"),
new TextRenderData("部门")
);
// 创建数据行
RowRenderData row1 = RowRenderData.build(
new TextRenderData("张三"),
new TextRenderData("28"),
new TextRenderData("技术部")
);
// 构建表格
TableRenderData table = Tables.of(header, row1)
.border(BorderStyle.DEFAULT)
.create();
// 添加到数据
Map<String, Object> data = new HashMap<>();
data.put("employeeTable", table);
}
}
3 条件渲染
// 使用条件标签
// 模板中:{{?isImportant}}重要内容{{/isImportant}}
public class ConditionalExample {
public static void conditionalRender() throws Exception {
Map<String, Object> data = new HashMap<>();
// 条件为true时显示内容
data.put("isImportant", true);
// 也可以使用更复杂的条件
data.put("showWarning", false);
XWPFTemplate template = XWPFTemplate.compile("template.docx")
.render(data);
template.writeAndClose(new FileOutputStream("output.docx"));
}
}
批处理示例
public class BatchExample {
public static void batchFill() throws Exception {
List<Map<String, Object>> dataList = new ArrayList<>();
// 准备多组数据
for (int i = 0; i < 10; i++) {
Map<String, Object> data = new HashMap<>();
data.put("title", "报告-" + i);
data.put("date", "2024-01-" + (15 + i));
// 根据数据生成文件名
String outputPath = "output/report_" + i + ".docx";
XWPFTemplate template = XWPFTemplate.compile("template.docx")
.render(data);
template.writeAndClose(new FileOutputStream(outputPath));
}
}
}
异常处理
public class ErrorHandlingExample {
public static void safeFill() {
String templatePath = "template.docx";
String outputPath = "output.docx";
try (XWPFTemplate template = XWPFTemplate.compile(templatePath)) {
Map<String, Object> data = new HashMap<>();
data.put("title", "安全示例");
template.render(data);
template.writeAndClose(new FileOutputStream(outputPath));
System.out.println("文档生成成功");
} catch (IOException e) {
System.err.println("文件操作失败: " + e.getMessage());
} catch (Exception e) {
System.err.println("渲染失败: " + e.getMessage());
}
}
}
性能优化建议
// 1. 复用模板编译
public class TemplateCache {
private static final Map<String, XWPFTemplate> cache = new HashMap<>();
public static XWPFTemplate getTemplate(String path) throws Exception {
return cache.computeIfAbsent(path, p -> {
try {
return XWPFTemplate.compile(p);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
// 2. 使用线程池批量处理
public class BatchProcessor {
private final ExecutorService executor = Executors.newFixedThreadPool(4);
public void processBatch(List<Map<String, Object>> dataList) {
List<CompletableFuture<Void>> futures = dataList.stream()
.map(data -> CompletableFuture.runAsync(() -> {
try {
processDocument(data);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, executor))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.join();
}
}
注意事项
- 模板格式:推荐使用.docx格式
- 标签命名:避免使用特殊字符
- 图片处理:注意图片大小和格式
- 内存管理:大文档注意内存占用
- 版本兼容:确保poi-tl版本与POI版本兼容
这样就能灵活运用poi-tl进行Word文档的动态填充了。