Python自动化办公之如何用Excel拆分并自动发邮件

Python自动化办公之如何用Excel拆分并自动发邮件

今天我们来分享一个真实的自动化办公案例,希望各位 Python 爱好者能够从中得到些许启发,在自己的工作生活中更多的应用 Python,使得工作事半功倍!

需求

需要向大约 500 名用户发送带有 Excel 附件的电子邮件,同时必须按用户从主 Excel 文件中拆分数据以创建他们自己的特定文件,然后将该文件通过电子邮件发送给正确的用户

需求解析

640-376

大致的流程就是上图,先拆分 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()
640-379

可以看出,CUSTOMER_ID 就是那个唯一的用户 ID,下面我们以该字段来分组,得到如下数据


customer_group = df.groupby("CUSTOMER_ID")
for ID, group_df in customer_group:
    print(ID)
>>>Output>>>
A1000
A1001
A1002
A1005
...

我们再来看下用户 A1005 所对应的数据形式

640-375

接下来我们就为每一个用户创建一个 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 如下

640-377

我们已经收集了客户名单、他们的电子邮件和附件,现在我们就可以用 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"])
640-378

最后,我们再把所有生成的 Excel 存档,以备后面审查、比对等


archive_dir = Path.cwd() / "archive"

for f in attachments:
    shutil.move(f[1], archive_dir)

至此,我们的编码结束,整体来看还是比较简单的