Python自動化辦公之Excel拆分并自動發郵件
需求
需要向大約 500 名用戶發送帶有 Excel 附件的電子郵件,同時必須按用戶從主 Excel 文件中拆分數據以創建他們自己的特定文件,然后將該文件通過電子郵件發送給正確的用戶
需求解析
大致的流程就是上圖,先拆分 Excel 數據,提取出對應的郵件地址和用戶的數據信息,再自動添加到郵件的附件當中
代碼實現
首先我們先來看下我們手中 Excel 的數據形式是怎么樣的。
import datetime
import os
import shutil
from pathlib import Path
import pandas as pd
src_file = Path.cwd() / 'data' / 'Example4.xlsx'
df = pd.read_excel(src_file)
df.head()
可以看出,CUSTOMER_ID 就是那個唯一的用戶 ID,下面我們以該字段來分組,得到如下數據。
customer_group = df.groupby('CUSTOMER_ID')
for ID, group_df in customer_group:
print(ID)
>>>Output>>>
A1000
A1001
A1002
A1005
...
我們再來看下用戶 A1005 所對應的數據形式。
接下來我們就為每一個用戶創建一個 Excel,后面就可以作為附件使用。
attachment_path = Path.cwd() / 'data' / 'attachments'
today_string = datetime.datetime.today().strftime('%m%d%Y_%I%p')
attachments = []
for ID, group_df in customer_group:
attachment = attachment_path / f'{ID}_{today_string}.xlsx'
group_df.to_excel(attachment, index=False)
attachments.append((ID, str(attachment)))
我們來看下變量 attachments 所包含的數據吧。
[('A1000',
'c:\\Users\\luobo\\notebooks\\2020-10\\data\\attachments\\A1000_01162021_12PM.xlsx'),
('A1001',
'c:\\Users\\luobo\\notebooks\\2020-10\\data\\attachments\\A1001_01162021_12PM.xlsx'),
('A1002',
'c:\\Users\\luobo\\notebooks\\2020-10\\data\\attachments\\A1002_01162021_12PM.xlsx'),
('A1005',
'c:\\Users\\luobo\\notebooks\\2020-10\\data\\attachments\\A1005_01162021_12PM.xlsx')]
最后我們可以通過將 DataFrame 合并在一起來生成帶有電子郵件地址的文件列表。
email_merge = pd.merge(df, df2, how='left')
combined = email_merge[['CUSTOMER_ID', 'EMAIL', 'FILE']].drop_duplicates()
得到的 DataFrame 如下:
我們已經收集了客戶名單、他們的電子郵件和附件,現在我們就可以用 Outlook 發送一封電子郵件了。
import win32com.client as win32
today_string2 = datetime.datetime.today().strftime('%b %d, %Y')
class EmailsSender:
def __init__(self):
self.outlook = win32.Dispatch('outlook.application')
def send_email(self, to_email_address, attachment_path):
mail = self.outlook.CreateItem(0)
mail.To = to_email_address
mail.Subject = today_string2 + ' Report'
mail.Body = """Please find today's report attached."""
mail.Attachments.Add(Source=attachment_path)
# Use this to show the email
#mail.Display(True)
# Uncomment to send
#mail.Send()
通過上面這個簡單的類,我們可以生成電子郵件并附加 Excel 文件。
同時我們還注意到,這里使用了 win32,關于這個庫的具體使用,我們在下次的文章中再具體說明吧。
email_sender = EmailsSender()
for index, row in combined.iterrows():
email_sender.send_email(row['EMAIL'], row['FILE'])
最后,我們再把所有生成的 Excel 存檔,以備后面審查、比對等。
archive_dir = Path.cwd() / 'archive'
for f in attachments:
shutil.move(f[1], archive_dir)
至此,我們的編碼結束,整體來看還是比較簡單的。