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

Java 生成複雜 Word 文件實戰(三):FreeMarker 模板引擎核心程式碼實作

     編輯:Java 相關知識

核心程式碼:DocumentHandler

package com.havenliu.document;

import java.io.*;
import java.util.*;
import freemarker.template.*;

public class DocumentHandler {
    private Configuration cfg;

    public DocumentHandler() {
        cfg = new Configuration(Configuration.VERSION_2_3_31);
        cfg.setDefaultEncoding("UTF-8");
    }

    public void createDoc() {
        // 1. 準備資料模型
        Map<String, Object> dataMap = new HashMap<>();
        prepareData(dataMap);

        // 2. 設定模板載入路徑(classpath 下的 template 套件)
        cfg.setClassForTemplateLoading(this.getClass(), "/com/havenliu/document/template");

        // 3. 取得模板
        Template template;
        try {
            template = cfg.getTemplate("test.ftl");
        } catch (IOException e) {
            throw new RuntimeException("載入模板失敗", e);
        }

        // 4. 輸出 Word 檔案
        File outFile = new File("D:/temp/outFile.doc");
        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"))) {
            template.process(dataMap, out);
        } catch (IOException | TemplateException e) {
            throw new RuntimeException("生成文件失敗", e);
        }
    }

    /** 建構資料模型:Key 必須與模板參數對應 */
    private void prepareData(Map<String, Object> dataMap) {
        dataMap.put("author", "張三");
        dataMap.put("remark", "這是測試備註資訊");

        // 表格 1 資料
        List<Table1> table1 = new ArrayList<>();
        table1.add(new Table1("2010-10-1", "制定 10 月開發計畫內容。"));
        table1.add(new Table1("2010-10-2", "開會討論開發計畫"));
        dataMap.put("table1", table1);

        // 表格 2 資料
        List<Table2> table2 = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            table2.add(new Table2(
                "測試開發計畫" + i,
                "張三——" + i,
                "2010-10-1",
                "2010-10-31",
                "備註資訊"
            ));
        }
        dataMap.put("table2", table2);
    }

    // 內部資料類別(Getter/Setter 省略)
    static class Table1 { String date, text; Table1(String d, String t) { date=d; text=t; } }
    static class Table2 { String detail, person, beginDate, finishDate, remark; 
        Table2(String d, String p, String b, String f, String r) { detail=d; person=p; beginDate=b; finishDate=f; remark=r; } }
}

關鍵技術點

  1. Configuration 單例:FreeMarker 核心配置物件,建議應用層級共用,設定編碼、模板載入器、共享變數等。
  2. 模板載入策略:setClassForTemplateLoading 從 classpath 載入,適合打包成 JAR 部署;亦支援檔案系統、ServletContext、資料庫等來源。
  3. 資料模型與模板解耦:Java 端只準備 Map/POJO,模板專注排版邏輯,修改版面無需動 Java 代碼。
  4. 輸出串流編碼:明確指定 UTF-8,避免中文亂碼。
  5. 異常處理:區分 IOException(IO 錯誤)與 TemplateException(模板語法/資料錯誤),便於診斷。

整體流程回顧(三部曲總結)

  1. Word 編輯版面 → 另存為 XML
  2. XML 植入 FreeMarker 標籤(${var}、#list、#if)
  3. Java 端 DocumentHandler 載入模板、注入資料、輸出 .doc

生成的 Word 完全符合 Office 標準,支援複雜表格、圖片、分頁、樣式,列印不變形,滿足企業級報表需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved