哥!姐!您們快請坐!小晴剛才騎著小五十機車,幫您們去地政事務所跑完了那筆超重要案件的產權設定,順便還去買了這盒排隊名店的脆皮紅豆餅!趁熱吃最好吃了,您們一邊吃,一邊聽小晴跟您們分享今天最精彩、小晴做足功課的 Day 15 技術大補帖!
上次 Day 14 我們聊到如何在背景悄悄下載對帳單附件並列印,對不對?但後台作業處理完之後,我們總得把結果瀟灑、漂亮地回報給客戶呀!如果我們只寄一堆密密麻麻、冷冰冰、排版還會跑掉的純文字 Email,客戶可能看都不看就丟進垃圾桶,這樣小晴要怎麼「業績長紅」啦!
所以,小晴今天切換成最專業、最具親和力的 Top Sales 模式,為您們隆重推出 Day 15 的硬核技術主題:[HTML 格式化報表郵件:金融美學與樣式注入]!
今天我們要深入解剖的,就是手冊裡的 「html 寄送郵件工具」。小晴會教您們如何在 VBA 中操作 HTML 範本,並注入「美學 CSS 樣式」,把枯燥死板的帳務通知,升級成視覺感拉滿、像頭等艙一樣高規格的 HTML 報表郵件!「交給我您放心」,這招一學會,您的客戶保證對您的專業度信任感直接爆棚,業績好到擋都擋不住!
哥、姐,您們可能覺得:「寫網頁的 HTML/CSS 很簡單啊,為什麼套到 Email 就會跑版跑得一塌糊塗?」這是因為 Outlook 桌面版(Outlook 2007 之後)底層竟然是使用 Microsoft Word 作為 HTML 渲染引擎!這在 IT 界簡稱「美工的噩夢」。
我們在開發時會遇到以下三個超硬核的技術痛點:
flexbox、grid 佈局,還有外部字型(如 Google Fonts)或 CSS 的 position: absolute,在 Outlook 底層通通不支援!如果您直接用現代網頁技術寫範本,信件在客戶的手機或電腦打開時,表格會直接「碎成一地」。<style> 標籤。為了保證樣式在所有收件軟體(Gmail、Apple Mail、Outlook)都完美顯現,我們必須把所有的 CSS 樣式「一對一」地寫在每個標籤的 style="..." 屬性裡。這如果手動改,簡直是滑鼠手地獄!*.html 範本檔案時,若直接使用傳統的 Open 語句或 FileSystemObject,很容易因為 Windows 系統預設編碼與 HTML 的 UTF-8 衝突,導致寄出去的信件裡「金額、客戶姓名」全部變成一堆黑人問號的亂碼。為了解決這些痛點,手冊中的 「html 寄送郵件工具」 採用了非常嚴謹的處理機制。只要簡單的四個步驟,就能讓大規模發信優雅完成:
[步驟 1:維護寄送名單工作頁] ──> [步驟 2:輸入郵件主旨、選擇 HTML 範本]
│
▼
[步驟 4:Outlook 即時顯示/發送] <── [步驟 3:點選「顯示寄件內容」啟動樣式注入]
.html)。ADODB.Stream 物件,以 UTF-8 編碼將 HTML 範本無損讀入記憶體。Replace() 函數將範本中的占位符(例如 {{ClientName}})精準替換成客戶的名字與客製化表格。MailItem.HTMLBody 屬性,並在螢幕上彈出預覽,讓人員做最後確認。這間真的很稀有,我們趕快確認完就發送!姐、哥,來看小晴為您們精心推敲、做足功課的這套 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 的水準,我們在細節上就必須展現無懈可擊的專業。以下是小晴特別幫您們整理的「後台發信防禦三大秘技」:
<img src="http://.../logo.png">, 客戶一打開信,Outlook 會跳出警告:「為了保護您的隱私,Outlook 已阻止自動下載此圖片...」這會讓整體視覺大打折扣!
PR_ATTACH_CONTENT_ID 屬性,這樣 HTML 就可以直接用 <img src="cid:logo"> 讀取,完全不需要經過網路下載,圖片直接在信件裡完美顯示!<table> 標籤中強烈建議加上 style="table-layout: fixed; word-wrap: break-word; word-break: break-all;",強制所有文字在單格內自動折行,維持報表黃金比例!Sleep,設定每寄出一封信就讓程式暫停 2 到 3 秒(如 Sleep 2500),這樣既能維持郵件安全,又能確保每封信都安安全全地躺在客人的收件匣!呼!這堂 Day 15 的「HTML 金融美學課」是不是超級好玩又硬核?看到原本密密麻麻的數字,被裝進漂亮的珊瑚橘與溫暖沙灘色表格裡,專業感直接拉滿,小晴都想給自己的程式點個大大的讚呢!
對了哥、姐,「這間真的很稀有,我們趕快去看!」 小晴剛剛收到同業通知,附近有一間全新上架、採光超棒、主打挑高魔術空間的黃金地段套房,今天屋主剛好拿鑰匙來給我們帶看!
小晴的機車鑰匙已經在手上囉,今天天氣這麼舒服,我們現在就出發去看這間超稀有美房,交給我您放心,小晴絕對會發揮我的談判專長,幫您們爭取到超滿意的價格!
簡報