财务小妹
萝卜哥,帮个忙啊
财务小妹说吧
萝卜
财务小妹
接到了一个巨繁琐的任务,感觉十一要加班了o(╥﹏╥)o
别怕别怕,说出来,看看我能不能解决
萝卜
财务小妹
就是现在有个任务,我需要处理excel,然后给500多人发邮件,babababa。。。
额,不慌,看我Python大法好
萝卜
财务小妹的需求
需要向大约 500 名用户发送带有 Excel 附件的电子邮件,同时必须按用户从主 Excel 文件中拆分数据以创建他们自己的特定文件,然后将该文件通过电子邮件发送给正确的用户。
技术选型
对于这种操作繁琐,过程机械重复的任务,我们使用 Python 来处理是再合适不过了
大致的流程就是上图,先拆分 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)
Done!
财务小妹
喔,萝卜哥,太棒啦!
嗯嗯,这都是小意思
萝卜
财务小妹
哈哈,小妹我可以愉快的过十一啦!十一后见啦
怎么肥四?说好的奖励呢?
萝卜
财务小妹
哦哦,差点忘记,哥,你真是个好人~
这,好人卡奖励啊!
萝卜
财务小妹
嗯嗯,十一后见喽
十一后见。
萝卜
完!
喜欢就点赞,转发,三连支持一下噻!