【综合实战】实战:周报自动化(Excel→Word→邮件)
摘要:从 Excel 数据一键生成 Word 周报文档,再通过 Outlook 自动群发给团队。整篇干货约 15 分钟跑通,复制粘贴即可用。
层级说明:本篇为跨工具实战,按 B 系刻度实为 L3 量级(VBA + Outlook 自动化 + AI API)。没有 VBA 基础先读 B7;只想要现成方案的,跟着第三步代码照抄也能跑通。
一、痛点引入
周五下午 4 点,你面前摊着三样东西:
- 一张 Excel 表,本周做了 12 件事、4 个数据指标、3 个下周计划;
- 一份上周写过的 Word 周报模板,你打算改改就用;
- Outlook 收件人列表,8 个同事 + 1 个老板。
接下来 1 小时你大概是这样过的:把 Excel 里 12 行事项复制粘贴到 Word 里(复制一行、选中正文一行、按 Ctrl+V,改字体、再粘下一行)→ 把上周模板里的"上上周数据"替换掉 → 写邮件、抄送 8 个人、附上周报 → 发送。
这套动作每周重复 1 次,每月 4 次,每年 48 次。 更让人崩溃的是:复制粘贴时一不小心就把第 7 行的事项贴到了第 6 行的位置,老板看完周报打回来让你"核实下数据"——又是半小时。
这篇文章就帮你把这一小时压到 5 分钟:Excel 里点一下宏,自动出 Word 周报、自动发邮件、自动抄送团队。中间不再有人肉复制粘贴,也不再有"张冠李戴"的串行错位。
这套流水线串了四个软件:Excel(数据源)+ AI(可选,帮写"本周小结"那段文字)+ Word(周报模板,自动填字段)+ Outlook(发邮件)。其中 Excel 是主战场,VBA 宏就放在 Excel 里跑,整条链由 Excel 触发。
二、目标产出
照着做完,你能拿到:
- 一张 Excel 数据表(叫"周报数据"):第一行表头,下面是本周要写进周报的"原材料"——周次、关键指标、本周完成事项、下周计划等。
- 一份 Word 模板(叫"周报模板.docx"):里面写好正文框架,关键位置留"占位字段"(如
{周次}{本周完成}{下周计划}{AI小结}),被宏自动替换。 - 一段 VBA 宏(放在 Excel 的
ThisWorkbook里):你每周只需在 Excel 里更新数据,然后按一下F5,自动完成——生成 Word 文档 → 保存到指定文件夹 → Outlook 创建邮件 → 填主题/正文/收件人 → 挂上周报附件 → 发送。 - (可选)一段 AI 调用代码:在你有 OpenAI / 通义千问 API Key 的情况下,AI 会自动根据你写的"本周完成事项"生成一段 100 字左右的"本周小结"塞进 Word;没有 API Key 时留空,宏照样跑。
前置条件:
- 电脑上有 Excel + Word + Outlook 三件套(Office 2016 及以上都行,本文按 Microsoft 365 / Office 2019 写)。
- Outlook 必须配好邮箱账户(公司 Exchange / 个人 IMAP 都行),能正常点"发送"邮件。
- Excel 文件须 另存为
.xlsm(启用宏的工作簿),不然宏保存不住。 - 第一次跑宏前,要把宏文档放进受信任位置(文件 → 选项 → 信任中心 → 受信任位置,比全局"启用所有宏"更稳妥;仅自己电脑用),且 Outlook 信任中心里 "编程访问" 要设成不弹警告(避坑指南会细讲)。
- (可选)有任一 LLM 的 API Key,没有也能跑,只是周报里少一段 AI 小结。
三、案例实战
咱们的整条流水线分四步走,前两步准备材料(Excel 数据 + Word 模板),第三步写 VBA 跑通 Excel → Word,第四步串上 Outlook 群发邮件。每步都照着点、照着粘,结尾就能跑。
第一步:准备 Excel 数据源
邮件合并型自动化的"原材料"是一张表。第一行是列名(表头),下面每一行是一份周报的"数据"。咱们搞张简洁的:
第一步(新建工作簿): 打开 Excel → 新建一个空白工作簿 → 另存为 周报自动化.xlsm(注意是 .xlsm,不是 .xlsx,不然存不住宏)。
第二步(建表): 在第一个工作表里,把下面的表头和数据填进去。表名可以改成你想叫的(比如"周报数据"),但下面 VBA 里有一行常量 DATA_SHEET = "周报数据",改表名记得同步改 VBA 里的常量。
| A 列:周次 | B 列:关键指标 | C 列:本周完成 | D 列:下周计划 | E 列:收件人邮箱 |
|---|---|---|---|---|
| 2025-W42 | 销售 120 万 / 新客 23 / 续约率 78% | 完成 Q4 促销方案;上线新品 A;客户拜访 5 家 | 跟进新品 A 复购;准备双 11 物料 | team@company.com; boss@company.com |
关键点:本周完成 / 下周计划这两列内容多行时,在单元格里换行要按
Alt + Enter(单元格内换行),别直接敲回车(那会跳到下一行、把一份周报拆成两份)。
第三步(让 AI 帮你整理"本周完成"和"下周计划"两条列): 如果你这周事多且乱,可以先把零散的口水话发给 AI,让它帮你压成 5–8 条"像周报里的话"。提示词可以直接复制:
我本周做了下面这些零散的事。请帮我整理成 5 条"周报里能直接用"的要点,每条不超过 30 字,
动词开头,结果明确;如果提到数字请原样保留,不要编造。
- 跟销售开 2 次会,确定 Q4 主推品
- 写了新品 A 的详情页文案初稿
- 跟设计对接了详情页配图,改了 3 稿
- 拜访了 3 家老客户,谈到续约意向
- 内部培训做了 1 次,反馈一般
- 数据:本周销售 120 万,新客 23,续约率 78%AI 整理完贴回 C 列即可。这一步 AI 干的是"把口水话变周报话"的活,跟"AI 一键生成小结"是两回事——那个是后面 VBA 调用 API 干的。
第二步:制作 Word 周报模板
Word 模板是固定正文 + 占位字段。宏会自动把 Excel 数据"塞"进字段里,所以模板只写一次,以后每周改 Excel 数据就行,Word 模板不动。
第一步(写正文): 打开 Word → 新建文档 → 写一份这样的周报模板:
【{周次} 工作周报】
各位好,本周工作汇报如下。
一、关键指标
{关键指标}
二、本周完成事项
{本周完成}
三、本周小结
{AI小结}
四、下周计划
{下周计划}
—— {发件人}把内容里的 {周次} {关键指标} {本周完成} {下周计划} {AI小结} {发件人} 先用手敲成大括号包字的样子就行(后面宏会用"查找替换"自动改成 Excel 里的真数据)。注意大括号必须是英文 { },别打成中文 {}。
第二步(保存模板): 文件 → 另存为 → 路径填 C:\模板\周报模板.docx(**这里要先建好 C:\模板\ 文件夹**,跟 VBA 里的 TEMPLATE_PATH 常量保持一致)。
关键点:别把模板和 Excel 放在同一路径下,不然以后每周生成的"周报_20251025.docx"会和模板搞混。模板放只读文件夹,输出放专门文件夹,是好习惯。
第三步:写 VBA 宏(Excel → Word)
VBA(Visual Basic for Applications)=Office 自带的一套"写程序"的语言,专门用来把重复操作串起来。
第一步(开 VBA 编辑器): 回到 周报自动化.xlsm → 按 Alt + F11 → 左侧"工程资源管理器"里找到你的工作簿(名字是 VBAProject (周报自动化.xlsm))→ 双击 ThisWorkbook(不是新建模块,直接用 ThisWorkbook 即可,宏跟着工作簿走)。
第二步(粘代码 + 改配置): 把下面这段完整代码粘进右侧代码窗口。代码开头"配置区"里有 4 个常量,必须改成你自己的路径和收件人:
vbaSub 一键生成周报并群发邮件()
'=============================================
'功能:读 Excel 数据 → 生成 Word 周报 → Outlook 群发
'用法:每周更新"周报数据"表 → 光标放在本宏里 → 按 F5
'前提:Word 模板已就位、Outlook 已登录、信任中心已放行
'=============================================
'—————— 配置区(按你实际情况改)——————
Const DATA_SHEET As String = "周报数据" '★ 数据所在工作表名
Const TEMPLATE_PATH As String = "C:\模板\周报模板.docx" '★ Word 模板路径
Const OUTPUT_FOLDER As String = "C:\周报输出\" '★ 周报输出文件夹
Const EMAIL_SUBJECT As String = "本周工作周报" '★ 邮件主题前缀
Const SENDER_NAME As String = "张三" '★ 发件人(显示在正文署名)
'—————— 配置区结束 ——————
Dim ws As Worksheet
Dim fso As Object
Dim wordApp As Object, doc As Object
Dim outlookApp As Object, mail As Object
Dim weekRange As String, kpi As String, completed As String
Dim nextPlan As String, recipients As String
Dim outputPath As String
'—— 1. 读 Excel 数据(按行 2 取,可按需扩展)——
Set ws = ThisWorkbook.Worksheets(DATA_SHEET)
weekRange = CStr(ws.Range("A2").Value) '周次
kpi = CStr(ws.Range("B2").Value) '关键指标
completed = CStr(ws.Range("C2").Value) '本周完成
nextPlan = CStr(ws.Range("D2").Value) '下周计划
recipients = CStr(ws.Range("E2").Value) '收件人(多个用 ; 分隔(英文分号,MAPI 标准))
'—— 2. 自动建输出文件夹(容错:不存在就建)——
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(OUTPUT_FOLDER) Then fso.CreateFolder OUTPUT_FOLDER
'—— 3. 基于模板创建 Word 文档 + 字段替换 ——
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = False '不弹 Word 窗口;想看过程就改 True
Set doc = wordApp.Documents.Add(Template:=TEMPLATE_PATH, NewTemplate:=False)
'用"查找替换"填字段(占位符是 {周次} 这种大括号字串)
With doc.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = 1 'wdFindContinue(搜到末尾继续从头搜;0 才是 wdFindStop)
Dim fieldList As Variant
fieldList = Array( _
Array("{周次}", weekRange), _
Array("{关键指标}", kpi), _
Array("{本周完成}", completed), _
Array("{下周计划}", nextPlan), _
Array("{AI小结}", ""), _ '先留空,下一步会用 AI 填(或保持空)
Array("{发件人}", SENDER_NAME))
Dim i As Long
For i = LBound(fieldList) To UBound(fieldList)
.Text = CStr(fieldList(i)(0))
.Replacement.Text = CStr(fieldList(i)(1))
.Execute Replace:=2 '2 = wdReplaceAll
Next i
End With
'—— 4. 保存为新文档(文件名带日期)——
outputPath = OUTPUT_FOLDER & "周报_" & Format(Now, "yyyymmdd_hhnnss") & ".docx"
doc.SaveAs2 outputPath
doc.Close SaveChanges:=False
wordApp.Quit
'—— 5. Outlook 创建邮件 + 挂附件 + 发送 ——
Set outlookApp = CreateObject("Outlook.Application")
Set mail = outlookApp.CreateItem(0) '0 = olMailItem
mail.To = recipients
mail.Subject = EMAIL_SUBJECT & " - " & weekRange
'★ 普通文本邮件(不会被邮箱判垃圾)。想要 HTML 排版把 Body 改成 HTMLBody。
mail.Body = "各位好," & vbCrLf & vbCrLf & _
"本周工作周报见附件,请查阅。" & vbCrLf & _
"如有疑问请直接回复邮件。" & vbCrLf & vbCrLf & _
"—— " & SENDER_NAME
mail.Attachments.Add outputPath
'★ mail.Send = 立刻发送;想先检查再发改成 mail.Display,手动点 Send
mail.Send
MsgBox "搞定!" & vbCrLf & _
"周报已生成:" & outputPath & vbCrLf & _
"邮件已发送给:" & recipients, vbInformation, "周报自动化"
End Sub关键点(动手前请通读 3 遍):
- 改了路径/常量要保存:改了配置区后,按
Ctrl + S保存,再关掉 VBA 编辑器回到 Excel。- 第一次跑宏会被 Outlook 拦:会弹"是否允许程序发送邮件"的窗,必须点"是",且信任中心要放行(避坑指南第 2 条细讲)。
- 模板字段要英文大括号:上面 VBA 里写的是
{周次}这种英文半角大括号。Word 模板正文里也得是英文半角,别打成{周次},不然宏替换不到。
第三步(先空跑一次): 在 Excel 里光标点代码内部任意位置 → 按 F5 → 弹窗显示"搞定" + 周报路径 + 收件人 → 去 C:\周报输出\ 看有没有 周报_20251025_xxx.docx → 打开看一眼字段都填对没 → 去 Outlook **已发送邮件**里看邮件是否真的发出去了(如果走 mail.Display 而不是 mail.Send,不会真发,会停在 Outlook 里让你检查)。
关键点(建议先
Display后Send):第一次跑或者你还不放心,把代码里的mail.Send临时改成mail.Display,宏会停一封写好的邮件在 Outlook 窗口里,你点开看一眼正文、附件都对,再手动点"发送"。确认 OK 后改回mail.Send,从此一键到位。
第四步:(可选增强)让 AI 写"本周小结"
如果你有 OpenAI / 通义千问 / 文心一言等 LLM 的 API Key,可以让 AI 根据你 Excel 里的"本周完成"自动写一段 100 字的"本周小结",塞进 Word 的 {AI小结} 占位符。
第一步(拿 API Key): 注册 OpenAI(platform.openai.com)或通义千问(dashscope.aliyun.com)、或文心一言(cloud.baidu.com)的账号 → 在控制台创建 API Key → 复制。
第二步(在 Excel VBA 里新增模块): Alt + F11 → 左侧工程里右键 → 插入 → 模块 → 把下面代码粘进去(这是单独函数,会被第三步里那段主宏调用):
vbaFunction 调用AI生成小结(ByVal completed As String, ByVal kpi As String) As String
'—— 代码用 CreateObject 后期绑定,无需手动添加引用 ——
'—— 没 API Key 时本函数直接返回空字符串,主宏照样跑。——
Const API_KEY As String = "sk-XXXXXX" '★ 换成你自己的 API Key
Const API_URL As String = "https://api.openai.com/v1/chat/completions"
Const MODEL_NAME As String = "gpt-4o-mini"
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
'构造 prompt:明确"不编数字、100 字内"
Dim sysPrompt As String
sysPrompt = "你是一个简洁的周报助手,根据用户输入的事实写一段不超过 100 字的本周小结。不要编造任何数字,不要出现感叹号和套话。"
Dim userPrompt As String
userPrompt = "本周完成:\n" & completed & "\n\n关键指标:\n" & kpi
'手工拼 JSON(避免引用 JSON 库)
Dim reqBody As String
reqBody = "{""model"":""" & MODEL_NAME & _
""",""messages":[{" & _
"""role"":""system"",""content"":""" & EscapeJson(sysPrompt) & _
"""},{" & _
"""role"":""user"",""content"":""" & EscapeJson(userPrompt) & _
"""}],""temperature"":0.3}"
On Error GoTo AI_Fail
http.Open "POST", API_URL, False
http.setRequestHeader "Content-Type", "application/json"
http.setRequestHeader "Authorization", "Bearer " & API_KEY
http.send reqBody
Dim response As String
response = http.responseText
'—— 状态码兜底:非 200 一律视为失败,直接走 AI_Fail 出口 ——
If http.status <> 200 Then
Debug.Print http.status & ": " & Left(response, 200)
GoTo AI_Fail
End If
'极简 JSON 解析:从 responseText 里挖出 content 字段
Dim startPos As Long, endPos As Long
startPos = InStr(response, """content"":""")
If startPos > 0 Then
startPos = startPos + Len("""content"":""")
endPos = InStr(startPos, response, """")
If endPos > startPos Then
'够用版先看 status,生产版换 ScriptControl 做 JSON.parse
调用AI生成小结 = UnescapeJson(Mid(response, startPos, endPos - startPos))
Exit Function
End If
End If
AI_Fail:
'任何错误都返回空,让主宏继续走(不要因为 AI 失败把整条邮件流打断)
调用AI生成小结 = ""
End Function
'—— 两个 JSON 转义辅助函数 ——
'(如输入含反斜杠或 Unicode,建议引入 ScriptControl 或 VBA-JSON 库)
Private Function EscapeJson(ByVal s As String) As String
s = Replace(s, "\", "\\")
s = Replace(s, """", "\""")
s = Replace(s, vbLf, "\n")
s = Replace(s, vbCr, "\r")
EscapeJson = s
End Function
Private Function UnescapeJson(ByVal s As String) As String
'—— 极简反转义:按固定顺序替换。局限:若正文本身含 \\n 这类字符仍可能还原错,严谨做法是单遍扫描解析或用 JSON 库 ——
s = Replace(s, "\\", Chr(92)) '先用 Chr(92) 把 JSON 转义反斜杠 \\ 还原成单个 \
s = Replace(s, "\n", vbLf)
s = Replace(s, "\r", vbCr)
s = Replace(s, "\""", """")
UnescapeJson = s
End Function第三步(让主宏调它): 回到 ThisWorkbook 里那段主宏,找到字段替换那一段(.Text = "{AI小结}" 那一行),把它的值从 "" 改成 调用AI生成小结(completed, kpi):
vba'原来:
Array("{AI小结}", ""),
'改成:
Array("{AI小结}", 调用AI生成小结(completed, kpi)),第四步(跑一遍): 回到 Excel,光标放主宏里 → F5。这时 {AI小结} 那一段会被 AI 自动填好的文字替换。如果 API 报错,主宏不会崩——调用AI生成小结 函数会返回空字符串,周报照样生成。
关键点(API 选型注意):
- OpenAI:示例用的是
gpt-4o-mini,便宜好用;通义千问把API_URL换成https://dashscope.aliyun.com/compatible-mode/v1/chat/completions、模型名换成qwen-turbo即可(接口兼容 OpenAI 格式,改两行就够)。通义 API Key 在阿里云百炼控制台获取(sk-开头),Bearer 头不变;环境变量建议用DASHSCOPE_API_KEY。- API Key 千万别写进公开文件:如果周报自动化文件要发给同事,务必把
API_KEY那行单独存到另一个地方,或者用环境变量读(Environ("OPENAI_API_KEY"))。- 没 API Key 也别慌:直接跳过第四步,只跑前三步的纯 VBA 方案,80% 的价值已经到手——从"周五下午 1 小时"压到"5 分钟"的核心是 VBA 自动生成 + 自动发邮件,AI 小结只是锦上添花。
(备选)不会 VBA?用 Power Automate 也能搞定
如果你公司不让装宏、或者你完全不想碰 VBA,Power Automate(微软的低代码自动化平台)能搭一条几乎一样的流水线。思路三步:
- 触发器:用"计划"触发器,设每周五 16:00 自动跑。
- 读 Excel:用"OneDrive for Business / SharePoint"里的 Excel 文件 + "获取行"动作,读出本周数据。
- 创 Word + 发邮件:用"填充 Word 模板"动作基于 SharePoint 里的模板生成周报,再用"发送邮件(V2)"动作挂上周报附件发给收件人列表。
这套思路的好处是完全不碰代码;代价是依赖微软云(OneDrive / SharePoint / Exchange Online),公司没有 M365 订阅就用不了。VBA 方案完全本地——只要你的电脑装 Office 三件套就能跑。两种思路随你挑,本文 VBA 为主、Power Automate 为辅。
四、原理小结
一句话讲清底层:VBA 是 Office 自带的"会写代码的胶水",把 Excel、Word、Outlook 这三个本来各管各的软件,通过**COM(Component Object Model,组件对象模型——简单理解就是 Office 程序之间互相打招呼的一套协议)**串成一条流水线。Excel 用 CreateObject("Word.Application") 把 Word 喊起来、用 Documents.Add 喊它基于模板新建一个文档、用 Range.Find 喊它把字段替换掉、用 SaveAs2 喊它存盘;然后用 CreateObject("Outlook.Application") 把 Outlook 喊起来、用 CreateItem(0) 喊它造一封邮件、用 Send 喊它发出去。整条链没有一个鼠标点击,全是 VBA 在背后替你按。AI 在这条链里只干一件事:在"Excel 数据 → Word 周报正文"的转换中,加一段"本周小结"的润色——本质是把 Excel 里的"事实"翻译成"人话",省掉你最费脑子想措辞的那 10 分钟。
五、避坑指南
- 宏点不开 / Excel 一打开就禁宏? 默认 Office 是禁用宏的。把文件 另存为
.xlsm(启用宏的工作簿),然后把文件所在文件夹加入 文件 → 选项 → 信任中心 → 信任中心设置 → 受信任位置(比全局"启用所有宏"影响面小得多;公司电脑请咨询 IT)。 - Outlook 弹"是否允许程序发送邮件"的窗? 第一次跑宏必弹,必须手动点"是"。要想以后不再弹:文件 → 选项 → 信任中心 → 信任中心设置 → 编程访问,选"从不向我发出可疑活动警告"(同样只在自己电脑上用;Outlook 2016+ 装了杀毒软件后一般不再弹窗)。公司电脑多会被组策略锁死,这时可以改用
mail.Display手动点发送。 mail.Send报"无法发送"或邮件进了"草稿"? 99% 是 Outlook 没配好账户或没联网。先在 Outlook 里手动发一封邮件试试,能发出去再跑宏。公司 Exchange 有"撤回 / 审批"策略时,宏发的邮件可能进"待发"而不是已发送,正常。- 模板字段替换不上 / Word 里还是
{周次}? 三种可能:① 模板里打的是中文大括号{}(改回英文{});②fieldList数组里的字段名跟模板里拼写不一致(注意大小写、空格,比如{周 次}多打一空格就匹配不上);③ 模板里的字段被 Word 当成了拼写检查项,导致宏跑时 Word 自动改动了内容(一般不会出现,但保险起见跑宏前Application.ScreenUpdating = True看一下)。 - AI 调用报 401 / 429? 401 是 API Key 错或过期,重新去平台控制台生成;429 是请求太频繁被限流,给
调用AI生成小结函数开头加一行Application.Wait Now + TimeValue("00:00:02")减慢节奏。API 直接选国内厂商(通义 / GLM / Kimi 等的兼容模式,支付宝/微信可充值);网络不通就先注释掉调用AI生成小结那行的调用,纯 VBA 方案完整可用。 - Outlook "收件人"列多个邮箱用什么分隔?
mail.To设多个地址必须用英文分号;分隔,Outlook 全版本一致。若 Excel 单元格原本用了中文;或,,先用Replace标准化。
六、进阶延展
- 想让 Excel 数据源自己"长出来"? 实际工作中周报数据往往要从 CRM / 项目管理系统导,本篇假设你手工填。要自动抓,看 B2(用 AI 一键清洗脏数据,L2 入门篇):用 Power Query 把原始表洗成"周报数据"工作表,每月/周自动刷新一次,整条流水线就连成全自动;想深入 M 语言看 B26(用 AI 写 Power Query M 查询,L2 进阶篇)。
- 想让周报再生成 PPT 一并发出? Excel → Word → PPT 一条龙是典型汇报场景,看 B11(用 AI 把 Excel 数据自动生成汇报 PPT,L3 实战篇):本篇的 Excel 数据源结构可直接复用,再加一段 AI 生成 PPT 大纲的代码,整条链路补齐。
- 想给不同收件人发不同版本的周报? 比如老板看"完整版"、同事看"摘要版",这属于带判断的群发,进阶到 L3 的 B7(用 AI + 邮件合并批量生成通知):在 VBA 里按收件人决定套用哪份 Word 模板再发,本篇的"Excel 数据源 + VBA 串起来"思路正好是 B7 的前置能力。
- 想完全脱手? 周五 16:00 自动跑,不要人按 F5——把宏配合 Windows 任务计划程序(Win+R →
taskschd.msc)设定时触发,到点自动开 Excel 跑宏、关 Excel、邮件自动发出去。这是把单点自动化推到"无人值守"的最后一步。 - 不会 VBA 也能跑:本文给出了 Power Automate 备选思路,依赖 M365 订阅(OneDrive + SharePoint + Exchange)。想深入了解 Power Automate 与 VBA 的取舍,看 D4(本地 vs 云端 AI 选型) 和 B17–B20(PowerShell / 自动化脚本系列)。