首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 導出 Word 文件最佳實踐:FreeMarker + XML 模板方案(支援複雜樣式、表格、列表)

     編輯:Java 綜合教學

方案選型對比

方案優點缺點推薦場景
Jacob (COM)完美支援 Word 所有功能僅 Windows、需 Office 安裝、重依賴Windows 伺服器、極複雜排版
Apache POI (XWPF)純 Java、跨平台樣式支援有限、複雜表格難控制簡單文檔、純文字替換
Java2WordAPI 簡單、支援書籤/表格第三方閉源、維護不確定快速原型
iText (RTF/PDF)PDF 輸出強Word 輸出非原生最終需 PDF
JSP 輸出極簡單樣式控制弱、分頁困難極簡報表
FreeMarker + Word XML樣式 100% 保真、跨平台、模板可視化編輯模板製作需 Word 另存為 XML企業級報表、合同、複雜文檔首選

FreeMarker + Word XML 完整流程

步驟 1:設計 Word 模板

  1. Word 中排版好完整文檔(字型、段落、表格、頁眉頁腳、分頁符)
  2. 將動態內容標記為佔位符:${title}、${user.name}、${list[i].amount}
  3. 列表區域用 <#list list as item>...</#list> 包裹
  4. 另存為「Word XML 格式」(.xml),非 .docx

步驟 2:轉換為 .ftl 模板

  1. 用文字編輯器開啟 .xml
  2. 將佔位符確認為 FreeMarker 語法(已兼容)
  3. 另存為 template.ftl,放入 classpath (如 src/main/resources/templates)

步驟 3:Java 程式碼生成

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.32</version>
</dependency>

public class WordExporter {
    private final Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);

    public WordExporter() {
        cfg.setClassForTemplateLoading(this.getClass(), "/templates");
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    }

    public void export(Map data, String outputPath) throws Exception {
        Template t = cfg.getTemplate("contract.ftl");
        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"))) {
            t.process(data, out);
        }
    }
}

步驟 4:資料模型範例

Map data = new HashMap<>();
data.put("title", "合作協議書");
data.put("date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
data.put("partyA", "甲方公司");
data.put("partyB", "乙方公司");

List> items = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
    Map row = new HashMap<>();
    row.put("no", i);
    row.put("desc", "服務項目 " + i);
    row.put("price", 1000 * i);
    items.add(row);
}
data.put("items", items);  // 對應模板 #list items as item

模板關鍵語法速查

需求FreeMarker 語法
變數輸出${variable} / ${obj.prop}
空值預設${var!'預設值'}
列表迴圈<#list items as item> ${item.no} </#list>
條件判斷<#if user.vip>VIP<#else>普通</#if>
數字格式化${price?string.currency} / ${price?string['#,##0.00']}
日期格式化${date?string['yyyy-MM-dd']}
插入圖片Word 模板預留書籤 → Java 端用 POI 替換書籤為圖片 (混合方案)

進階:複雜表格跨頁、頁眉頁腳、目錄自動生成

  • Word XML 完整保留 w:tbl、w:hdr/w:ftr、w:toc 等結構
  • FreeMarker 僅替換文字節點,不破壞任何排版屬性
  • 生成的 .doc (實為 XML) 用 Word 開啟後另存為 .docx 即為標準格式

常見問題

  • 中文亂碼:模板檔案編碼必須 UTF-8,Java 端 OutputStreamWriter(..., "UTF-8")
  • XML 命名空間衝突:模板中 xmlns:w="..." 保持原樣,勿手動修改
  • 大檔案記憶體:FreeMarker 流式輸出,模板載入佔記憶體,超大模板可分片
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved