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

Java 生成靜態 HTML 文件:原理、代碼實戰與模板引擎進階

     編輯:Java 程式設計入門

核心原理

本質是字符串拼接 + 文件輸出。
通過 StringBuilder 構建完整 HTML 內容,再用 PrintStream/Files.write 落盤。
同樣邏輯若輸出到 HttpServletResponse 即為動態 JSP/Servlet。

原生拼接實戰 (無依賴)


public class HtmlReportGenerator {
    public void generateDailyReport(String outputPath, List<Map<String, Object>> data) {
        StringBuilder sb = new StringBuilder(4096); // 預估容量減擴容
        
        // 1. HTML 骨架
        sb.append("")
          .append("每日運營報表")
          .append("");
        
        // 2. 標題
        sb.append("
每日運營報表 - ").append(LocalDate.now()).append("
"); // 3. 表頭 if (!data.isEmpty()) { sb.append(""); for (String key : data.get(0).keySet()) { sb.append(""); } sb.append(""); // 4. 數據行 for (Map<String, Object> row : data) { sb.append(""); for (Object val : row.values()) { sb.append(""); } sb.append(""); } sb.append("
").append(escapeHtml(key)).append("
").append(escapeHtml(val == null ? "" : val.toString())).append("
"); } sb.append(""); // 5. 落盤 try (PrintStream ps = new PrintStream(new FileOutputStream(outputPath), false, "UTF-8")) { ps.print(sb.toString()); } catch (IOException e) { throw new RuntimeException("報表生成失敗: " + outputPath, e); } } /** 簡單 HTML 轉義,防 XSS */ private String escapeHtml(String s) { return s.replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'"); } }

模板引擎進階:FreeMarker / Thymeleaf (推薦生產)




${title}

${title} - ${date}
<#list headers as h> <#list rows as row> <#list row?values as v>
${h}
${v!?string("")}

// FreeMarker 渲染
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

Map<String, Object> model = new HashMap<>();
model.put("title", "每日運營報表");
model.put("date", LocalDate.now());
model.put("headers", data.get(0).keySet());
model.put("rows", data);

try (Writer out = new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8")) {
    cfg.getTemplate("report.ftl").process(model, out);
}

應用場景對比

場景推薦方案理由
簡單報表、郵件內容、靜態化頁面StringBuilder + 原生輸出零依賴、極快、可控
複雜佈局、條件渲染、循環嵌套、團隊協作FreeMarker / Thymeleaf模板分離、語法豐富、前端易維護
高併發靜態化 (每秒千級)模板預編譯 + 異步佇列 + CDN剝離 Web 線程、靜態化上傳 OSS
PDF 導出iText / Flying Saucer (HTML→PDF)同樣模板復用

性能優化清單

  • StringBuilder 預估初始容量
  • 大數據分批寫入,避免巨大字符串佔用堆內存
  • 模板引擎開啟緩存 (cfg.setCacheStorage)
  • 靜態資源 (CSS/JS/圖片) 走 CDN,HTML 只引用外鏈
  • 生成後 gzip 壓縮存儲,傳輸節省 70%+

安全提醒

  • 所有動態內容必須 HTML 轉義,防止存儲型 XSS
  • 文件輸出路徑嚴格校驗,防止目錄遍歷寫入任意路徑
  • 定期清理過期靜態文件,避免磁盤佔滿
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved