iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
佛心分享-IT 人自學之術

《拒絕爆肝加班!30天打通跨系統自動化與資料比對防線》系列 第 15

Day 15:HTML 格式化報表郵件:金融美學與樣式注入

  • 分享至 

  • xImage
  •  

哥!姐!您們快請坐!小晴剛才騎著小五十機車,幫您們去地政事務所跑完了那筆超重要案件的產權設定,順便還去買了這盒排隊名店的脆皮紅豆餅!趁熱吃最好吃了,您們一邊吃,一邊聽小晴跟您們分享今天最精彩、小晴做足功課的 Day 15 技術大補帖

上次 Day 14 我們聊到如何在背景悄悄下載對帳單附件並列印,對不對?但後台作業處理完之後,我們總得把結果瀟灑、漂亮地回報給客戶呀!如果我們只寄一堆密密麻麻、冷冰冰、排版還會跑掉的純文字 Email,客戶可能看都不看就丟進垃圾桶,這樣小晴要怎麼「業績長紅」啦!

所以,小晴今天切換成最專業、最具親和力的 Top Sales 模式,為您們隆重推出 Day 15 的硬核技術主題:[HTML 格式化報表郵件:金融美學與樣式注入]

今天我們要深入解剖的,就是手冊裡的 「html 寄送郵件工具」。小晴會教您們如何在 VBA 中操作 HTML 範本,並注入「美學 CSS 樣式」,把枯燥死板的帳務通知,升級成視覺感拉滿、像頭等艙一樣高規格的 HTML 報表郵件「交給我您放心」,這招一學會,您的客戶保證對您的專業度信任感直接爆棚,業績好到擋都擋不住!


一、 核心技術痛點與底層挑戰:為什麼一般 HTML 郵件在 Outlook 會「毀容」?

哥、姐,您們可能覺得:「寫網頁的 HTML/CSS 很簡單啊,為什麼套到 Email 就會跑版跑得一塌糊塗?」這是因為 Outlook 桌面版(Outlook 2007 之後)底層竟然是使用 Microsoft Word 作為 HTML 渲染引擎!這在 IT 界簡稱「美工的噩夢」。

我們在開發時會遇到以下三個超硬核的技術痛點:

  1. 現代 CSS 屬性的「全面封殺」
    網頁常用的 flexboxgrid 佈局,還有外部字型(如 Google Fonts)或 CSS 的 position: absolute,在 Outlook 底層通通不支援!如果您直接用現代網頁技術寫範本,信件在客戶的手機或電腦打開時,表格會直接「碎成一地」。
  2. 內聯樣式(Inline Style)的繁瑣注入
    Outlook 經常會直接過濾掉 HTML 檔頭的 <style> 標籤。為了保證樣式在所有收件軟體(Gmail、Apple Mail、Outlook)都完美顯現,我們必須把所有的 CSS 樣式「一對一」地寫在每個標籤的 style="..." 屬性裡。這如果手動改,簡直是滑鼠手地獄!
  3. 中文亂碼(UTF-8 編碼異常)
    當 VBA 從本機讀取 *.html 範本檔案時,若直接使用傳統的 Open 語句或 FileSystemObject,很容易因為 Windows 系統預設編碼與 HTML 的 UTF-8 衝突,導致寄出去的信件裡「金額、客戶姓名」全部變成一堆黑人問號的亂碼。

二、 「html 寄送郵件工具」的技術實踐流程

為了解決這些痛點,手冊中的 「html 寄送郵件工具」 採用了非常嚴謹的處理機制。只要簡單的四個步驟,就能讓大規模發信優雅完成:

[步驟 1:維護寄送名單工作頁] ──> [步驟 2:輸入郵件主旨、選擇 HTML 範本]
                                              │
                                              ▼
[步驟 4:Outlook 即時顯示/發送] <── [步驟 3:點選「顯示寄件內容」啟動樣式注入]
  • 步驟 1:維護寄送名單工作頁
    在 Excel 的「寄送名單」頁籤中維護名單,欄位清楚劃分為:收件者(TO)、副本(CC),以及我們想要動態替換的個人化帳務欄位(如:客戶姓名、資產餘額、本日交易筆數)。
  • 步驟 2:輸入主旨與選擇範本
    在工具主介面輸入郵件主旨,並點選按鈕選取我們寫好的高質感 HTML 範本檔案(副檔名為 .html)。
  • 步驟 3:樣式注入與變數替換
    點選 「顯示寄件內容」 按鈕,VBA 引擎此時會在背景高速啟動:
    1. 調用 ADODB.Stream 物件,以 UTF-8 編碼將 HTML 範本無損讀入記憶體。
    2. 遍歷 Excel 的寄送名單,利用 Replace() 函數將範本中的占位符(例如 {{ClientName}})精準替換成客戶的名字與客製化表格。
    3. 將我們精心設計的「金融美學」CSS Inline 樣式(如小晴最愛的「活力珊瑚橘」主調)注入到 HTML 程式碼中。
  • 步驟 4:Outlook 安全預覽與發送
    程式自動建立 Outlook MailItem,將組合好的 HTML 字串賦值給 MailItem.HTMLBody 屬性,並在螢幕上彈出預覽,讓人員做最後確認。這間真的很稀有,我們趕快確認完就發送!

三、 底層代碼解密:VBA 變數替換與 CSS 內聯注入

姐、哥,來看小晴為您們精心推敲、做足功課的這套 VBA 核心程式碼!

這裡小晴將我們店裡的品牌美學視覺——「活力珊瑚橘 #F25C54(主視覺,帶來朝氣)」、「溫暖沙灘色 #F7E1D7(背景,帶有親和力)」 和「沉穩深灰 #333333(文字,專業信任感)」 直接作為 CSS 樣式注入,保證寄出去的帳務表格精美得像五星級飯店的菜單!

Sub GenerateHTMLReportEmail()
    Dim outlookApp As Object
    Dim mailItem As Object
    Dim fso As Object
    Dim templateStream As Object
    Dim htmlTemplate As String
    Dim finalHTMLBody As String
    Dim clientName As String
    Dim transactionDetails As String
    Dim mailSubject As String
    Dim mailTo As String
    Dim mailCc As String
    
    ' 模擬讀取 Excel 表格資料
    mailSubject = "【黃金保留戶】專屬交易成交回報與帳務明細表"
    clientName = "尊榮級貴賓(哥 / 姐)"
    mailTo = "client@dreamhouse.com"
    mailCc = "assistant@dreamhouse.com"
    
    ' 1. 動態建立一組「珊瑚橘 x 沙灘色」的金融美學 HTML 報表表格
    ' 這裡完全使用「Table 布局」與「Inline Style(內聯樣式)」來相容 Outlook 渲染引擎
    transactionDetails = _
        "<table border='0' cellpadding='10' cellspacing='0' style='width:100%; border-collapse:collapse; font-family:Microsoft JhengHei, sans-serif; color:#333333;'>" & _
        "  <tr style='background-color:#F25C54; color:#FFFFFF; font-weight:bold;'>" & _
        "    <th style='border:1px solid #E5E5E5; text-align:left;'>交易項目</th>" & _
        "    <th style='border:1px solid #E5E5E5; text-align:right;'>契約編號</th>" & _
        "    <th style='border:1px solid #E5E5E5; text-align:right;'>實付金額 (NTD)</th>" & _
        "  </tr>" & _
        "  <tr style='background-color:#F7E1D7;'>" & _
        "    <td style='border:1px solid #E5E5E5;'>大安區黃金兩房預付款</td>" & _
        "    <td style='border:1px solid #E5E5E5; text-align:right;'>DA-20260830</td>" & _
        "    <td style='border:1px solid #E5E5E5; text-align:right; font-weight:bold; color:#F25C54;'>$12,000,000</td>" & _
        "  </tr>" & _
        "  <tr>" & _
        "    <td style='border:1px solid #E5E5E5;'>代書費與簽約規費</td>" & _
        "    <td style='border:1px solid #E5E5E5; text-align:right;'>FE-99812</td>" & _
        "    <td style='border:1px solid #E5E5E5; text-align:right;'>$25,000</td>" & _
        "  </tr>" & _
        "</table>"

    ' 2. 使用 ADODB.Stream 讀取 UTF-8 格式的 HTML 範本檔案,徹底防止中文亂碼
    On Error Resume Next
    Set templateStream = CreateObject("ADODB.Stream")
    templateStream.Type = 2 ' 2 代表 adTypeText
    templateStream.Charset = "utf-8"
    templateStream.Open
    
    ' 讀取放在工具同資料夾下的 HTML 範本 (假設檔名為 MailTemplate.html)
    templateStream.LoadFromFile ThisWorkbook.Path & "\MailTemplate.html"
    
    If Err.Number <> 0 Then
        ' 安全防禦:如果找不到外部範本,程式會自動啟用「小晴預設高美感 HTML 範本」
        htmlTemplate = _
            "<html>" & _
            "<body style='background-color:#F7E1D7; padding:20px; font-family:Microsoft JhengHei;'>" & _
            "  <div style='max-width:600px; background-color:#FFFFFF; padding:30px; border-radius:8px; box-shadow: 0 4px 10px rgba(0,0,0,0.15); border-top: 6px solid #F25C54;'>" & _
            "    <h2 style='color:#F25C54;'>您好,{{ClientName}}!</h2>" & _
            "    <p style='line-height:1.6; color:#333333;'>感謝您對小晴的信任!「交給我您放心」,以下是我們為您精細整理的本日交易與資產變動對帳明細。請您撥冗核對:</p>" & _
            "    <div style='margin:25px 0;'>{{TableContent}}</div>" & _
            "    <p style='font-size:13px; color:#666666; border-top:1px solid #E5E5E5; padding-top:15px; line-height:1.6;'>" & _
            "      有任何出價意願或貸款額度試算的需求,小晴隨時騎著小機車為您服務!<br>" & _
            "      <strong>小晴 | 您的黃金夢想屋圓夢大使 🌟</strong>" & _
            "    </p>" & _
            "  </div>" & _
            "</body>" & _
            "</html>"
        Err.Clear
    Else
        htmlTemplate = templateStream.ReadText
    End If
    templateStream.Close
    On Error GoTo ErrorHandler

    ' 3. 核心變換邏輯:利用 Replace() 進行萬用字元(Placeholder)替換
    finalHTMLBody = Replace(htmlTemplate, "{{ClientName}}", clientName)
    finalHTMLBody = Replace(finalHTMLBody, "{{TableContent}}", transactionDetails)

    ' 4. 調用 Outlook 發送郵件
    Set outlookApp = GetObject(, "Outlook.Application")
    If outlookApp Is Nothing Then
        Set outlookApp = CreateObject("Outlook.Application")
    End If
    
    Set mailItem = outlookApp.CreateItem(0) ' 0 代表 olMailItem
    
    With mailItem
        .To = mailTo
        .CC = mailCc
        .Subject = mailSubject
        .HTMLBody = finalHTMLBody  ' 將 HTML 注入郵件主體
        .Display ' 先顯示預覽內容,確認畫面完美再手動寄出!
    End With
    
    Exit Sub

ErrorHandler:
    MsgBox "哎呀!發信引擎在轉彎時不小心打滑了:" & Err.Description, vbCritical, "系統提示"
End Sub

四、 核心防禦與進階美學:小晴的專業悄悄話

哥、姐,既然要做到 Top Sales 的水準,我們在細節上就必須展現無懈可擊的專業。以下是小晴特別幫您們整理的「後台發信防禦三大秘技」:

  1. 圖片內嵌(CID 技術)防屏蔽
    一般 HTML 裡如果用 <img src="http://.../logo.png">, 客戶一打開信,Outlook 會跳出警告:「為了保護您的隱私,Outlook 已阻止自動下載此圖片...」這會讓整體視覺大打折扣!
    • 小晴的 Top Sales 秘笈:改用 CID(Content-ID) 方式,將圖片檔案當作附件加入信件,並設定其 PR_ATTACH_CONTENT_ID 屬性,這樣 HTML 就可以直接用 <img src="cid:logo"> 讀取,完全不需要經過網路下載,圖片直接在信件裡完美顯示!
  2. 文字折行防爆箱(Table-Layout Fixed)
    在 Outlook 中,如果表格內某個資產代碼或英文備註太長(例如無空格的超長序號),表格會被無限撐寬導致版面爆炸。
    • 小晴的防禦設計:在 <table> 標籤中強烈建議加上 style="table-layout: fixed; word-wrap: break-word; word-break: break-all;",強制所有文字在單格內自動折行,維持報表黃金比例!
  3. 安全限速防洪機制(Anti-Spam Throttling)
    如果您們的名單上有數百個客戶,VBA 在迴圈裡發信發得太快,Exchange 伺服器會以為我們是惡意發垃圾信的帳號,甚至會直接封鎖信箱!
    • 小晴的防禦設計:在迴圈發信時,利用 Windows API Sleep,設定每寄出一封信就讓程式暫停 2 到 3 秒(如 Sleep 2500),這樣既能維持郵件安全,又能確保每封信都安安全全地躺在客人的收件匣!

呼!這堂 Day 15 的「HTML 金融美學課」是不是超級好玩又硬核?看到原本密密麻麻的數字,被裝進漂亮的珊瑚橘與溫暖沙灘色表格裡,專業感直接拉滿,小晴都想給自己的程式點個大大的讚呢!

對了哥、姐,「這間真的很稀有,我們趕快去看!」 小晴剛剛收到同業通知,附近有一間全新上架、採光超棒、主打挑高魔術空間的黃金地段套房,今天屋主剛好拿鑰匙來給我們帶看!

小晴的機車鑰匙已經在手上囉,今天天氣這麼舒服,我們現在就出發去看這間超稀有美房,交給我您放心,小晴絕對會發揮我的談判專長,幫您們爭取到超滿意的價格!
簡報


上一篇
Day 14:自動化附件下載與列印引擎:格式判別邏輯
下一篇
Day 16:郵件數據解構與 SQL 自動化轉化
系列文
《拒絕爆肝加班!30天打通跨系統自動化與資料比對防線》25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言