如何在Apple Mail中复制草稿时保留邮件格式?Python邮件合并工具遇格式丢失及报错问题求助
如何在Apple Mail中复制草稿时保留邮件格式?Python邮件合并工具遇格式丢失及报错问题求助
我太懂你这个烦恼了——本来想靠Apple Mail的带格式草稿当模板做邮件合并,结果生成的新草稿全变成干巴巴的纯文本,还时不时报错,完全达不到预期效果对吧?我帮你梳理下问题根源,再给出针对性的修复方案。
问题出在哪?
你当前的做法是新建空白 outgoing 消息,再把原草稿的内容提取出来替换占位符后赋值过去,但这里有两个核心问题:
- Apple Mail新建的空白消息默认是纯文本格式,直接赋值原草稿的富文本内容时,Mail会把它当成纯文本解析,直接丢失所有格式标记(比如粗体、斜体的RTF/HTML标签)。
- 纯文本替换函数
replace_text直接处理原草稿的content,如果原内容是带格式标记的富文本,这种粗暴的纯文本替换可能会破坏标记结构,进一步导致格式丢失。
修复方案:直接复制原草稿而非新建消息
正确的思路应该是完整复制原草稿消息(这样会100%保留原格式),然后在复制出来的新草稿上修改占位符和收件人,最后保存为新草稿。这样既保留格式,又避免了新建消息的格式兼容问题。
具体代码修改
我把你的代码关键部分修改好了,你直接替换对应的函数即可:
1. 修改create_and_run_applescript函数
def create_and_run_applescript(selected_draft, df): """Generates and runs AppleScript to create email drafts in Apple Mail, preserving formatting.""" # 处理草稿不存在的情况,提前判断 script_header = f""" tell application "Mail" set targetDraft to (first message of drafts mailbox whose subject is "{selected_draft}") if targetDraft is missing value then error "Error: Draft with subject '{selected_draft}' was not found in Apple Mail!" end if """ script_body = "" # 为每一行数据生成AppleScript代码,注意转义双引号避免语法错误 for _, row in df.iterrows(): # 转义用户数据中的双引号,防止破坏AppleScript字符串结构 recipient_name = row['Name'].replace('"', '\\"') recipient_email = row['Email'].replace('"', '\\"') script_body += f""" tell application "Mail" -- 复制原草稿,完整保留所有格式 set newDraft to duplicate targetDraft to drafts mailbox tell newDraft -- 替换占位符:直接修改复制后的草稿内容,保留富文本格式 set draftContent to content set draftContent to my replace_text(draftContent, "[Name]", "{recipient_name}") set content to draftContent -- 清空原收件人,添加新收件人 delete every to recipient make new to recipient at end of to recipients with properties {{address:"{recipient_email}"}} -- 可选:指定发件人(如果需要覆盖原草稿的发件人) set sender to "info@nathaliedecoster.com" -- 保存修改后的新草稿 save end tell end tell """ script_footer = """ end tell on replace_text(theText, theSearch, theReplace) -- 安全替换文本,不破坏富文本标记 set AppleScript's text item delimiters to theSearch set theItems to every text item of theText set AppleScript's text item delimiters to theReplace set theText to theItems as text set AppleScript's text item delimiters to "" return theText end replace_text """ full_script = script_header + script_body + script_footer # 保存并执行AppleScript try: applescript_path = os.path.join(os.getcwd(), "mail_merge_preserve_formatting.scpt") with open(applescript_path, "w") as f: f.write(full_script) subprocess.check_output(["osascript", applescript_path]) messagebox.showinfo("Success", f"Successfully created {len(df)} formatted drafts in Apple Mail!") except subprocess.CalledProcessError as e: messagebox.showerror("AppleScript Error", f"Failed to generate drafts:\n{e.output.decode().strip()}")
2. 额外注意事项
- 确保原草稿是富文本格式:打开Apple Mail的原草稿,检查格式设置(顶部工具栏的“格式”选项,选择“富文本”而非“纯文本”)。
- 占位符要纯文本:原草稿中的
[Name]不要被任何格式(比如粗体、斜体)包裹,否则替换可能不生效。 - 特殊字符处理:代码里已经处理了双引号的转义,如果你的数据里还有其他特殊字符(比如反斜杠),可以再添加对应的转义逻辑。
为什么这个修改能解决问题?
- 使用
duplicate targetDraft to drafts mailbox命令直接复制原草稿,相当于在Apple Mail里手动复制草稿,所有的格式(粗体、斜体、字体、颜色等)都会完整保留。 - 在复制后的草稿上直接修改内容,Mail会自动识别原格式,替换占位符后不会改变原有格式。
- 增加了草稿存在性检查,能提前告诉你目标草稿找不到,避免模糊的报错信息。
备注:内容来源于stack exchange,提问作者Alexis




