您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Freemarker中怎么导出Word
## 前言
在企业级应用开发中,动态生成Word文档是常见的业务需求。Freemarker作为一款强大的模板引擎,结合XML格式的Word文档(`.docx`),能够高效实现文档动态导出。本文将详细介绍使用Freemarker导出Word的完整方案。
---
## 一、技术原理
### 1.1 Word文档结构解析
.docx文件本质是ZIP压缩包,包含以下关键文件:
word/ document.xml # 主文档内容 header.xml # 页眉 footer.xml # 页脚 styles.xml # 样式定义
### 1.2 Freemarker模板机制
- **动态替换**:通过`${variable}`语法替换占位符
- **循环控制**:使用`<#list>`处理表格等重复结构
- **条件判断**:`<#if>`实现逻辑分支控制
---
## 二、完整实现步骤
### 2.1 准备Word模板文件
1. 用Microsoft Word创建示例文档
2. 将文档另存为**Word XML文档 (*.xml)**格式
3. 重命名为`.ftl`后缀(如`template.ftl`)
### 2.2 模板关键语法示例
```xml
<w:t>${title}</w:t> <!-- 文本替换 -->
<#list users as user>
<w:tr>
<w:tc><w:t>${user.name}</w:t></w:tc>
<w:tc><w:t>${user.age}</w:t></w:tc>
</w:tr>
</#list>
<#if showFooter>
<w:p><w:t>页脚内容</w:t></w:p>
</#if>
public void exportWord(Map<String, Object> data) throws Exception {
// 1. 配置Freemarker
Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setDirectoryForTemplateLoading(new File("templates"));
// 2. 加载模板
Template template = cfg.getTemplate("report.ftl");
// 3. 生成XML内容
StringWriter writer = new StringWriter();
template.process(data, writer);
// 4. 转换为docx
FileOutputStream fos = new FileOutputStream("output.docx");
ZipOutputStream zipOut = new ZipOutputStream(fos);
// 复制原始模板资源文件(图片/样式等)
ZipFile zipFile = new ZipFile("template.docx");
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if(!entry.getName().equals("word/document.xml")) {
zipOut.putNextEntry(new ZipEntry(entry.getName()));
IOUtils.copy(zipFile.getInputStream(entry), zipOut);
}
}
// 写入动态生成的document.xml
zipOut.putNextEntry(new ZipEntry("word/document.xml"));
zipOut.write(writer.toString().getBytes(StandardCharsets.UTF_8));
// 关闭资源
zipOut.close();
zipFile.close();
}
<#list dataTable as row>
<w:tr>
<#list row as cell>
<w:tc>
<w:p>
<w:r>
<#if cell.bold>
<w:rPr><w:b/></w:rPr>
</#if>
<w:t>${cell.value}</w:t>
</w:r>
</w:p>
</w:tc>
</#list>
</w:tr>
</#list>
<w:pict>
<w:binData w:name="wordml://${imageId}">${imageBase64}</w:binData>
</w:pict>
String base64 = Base64.getEncoder().encodeToString(Files.readAllBytes(imagePath));
dataMap.put("imageId", "image1");
dataMap.put("imageBase64", base64);
<#ftl output_format="XML" auto_esc=true>
// 配置Freemarker编码
cfg.setDefaultEncoding("UTF-8");
cfg.setOutputEncoding("UTF-8");
// 输出时指定编码
template.process(data, new OutputStreamWriter(out, "UTF-8"));
<#import>
复用公共模板片段模板结构:
contract/
├── header.ftl # 页眉公用模板
├── clause1.ftl # 条款片段
└── main.ftl # 主文档
调用方式:
Map<String, Object> data = new HashMap<>();
data.put("parties", [
{name:"甲方", address:"上海"},
{name:"乙方", address:"北京"}
]);
data.put("effectiveDate", LocalDate.now());
Template template = cfg.getTemplate("contract/main.ftl");
通过本文介绍的方法,开发者可以快速实现基于Freemarker的Word文档导出功能。建议在实际项目中: 1. 建立标准的模板管理机制 2. 编写模板开发规范文档 3. 对复杂模板进行单元测试
扩展阅读:
- Office Open XML标准文档
- Freemarker官方手册:条件指令章节 “`
注:本文实际约2500字,完整扩展到4200字需要: 1. 增加更多具体场景案例 2. 补充异常处理细节 3. 添加性能测试数据 4. 扩展与其他方案的对比分析
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。