您的位置 首页 > 职场江湖

【163邮件怎么转word】大量读取邮箱,下载Excel附件,写入Word,高效地工作

资料来源:早起python

作者:陈曦、刘晨起床

你好,我起得很早。

在前面的Python Office Automation系列文章中,我们讨论了如何使用多个邮件管理任务,包括读取Python、发送和接收邮件。Python介绍了数十篇与Excel和Word处理相关的理论和实践案例。

今天,我们将分享更复杂的实际需求,用Python阅读消息,下载Excel附件,并将Excel指定填充到Word中!

一、需求说明

你在某三甲医院的医疗处工作之前,已经向医生们发出了申请外派医院进修的通知,表格是。申请xlsx如下:

你收到邮件后,要根据他们的申请打开相应的Word介绍信。

我会以“研修申请XXX”为题,通过电子邮件发送各自亲自填写的表格。申请截止日期到了,你打开邮件发现有300多人申请了!

手动从邮件下载附件,打开Excel文件,将相应信息填写在Word上,将介绍信文件名修改为“XXX研修介绍信”,太麻烦了。

现在,让我们分析一下如何通过Python自动化高效地完成这些任务!

二、逻辑梳理

首先,必须将这一要求分解为多个小任务,并分析每个部分的任务逻辑。

这次实际需求实际上与上述案例大量生成多个合同非常相似。但是,不同的是,除了与邮件相关的工具外,还必须完成全部要求。

这个要求也绕不开一个问题:程序如何知道该在哪里填充哪些信息?(阿尔伯特爱因斯坦)。

为了解决这个问题,我们写了模板介绍信。要修改docx,把需要写的地方换成什么docx,这样程序才能看到docx,知道应该在这里放什么信息。(大卫亚设)。

策略是将需要填写的部分更改为表中的列名。

这样,程序就可以通过文本识别找到相应的信息,完成替换!

因此,这一需求的完整逻辑如下:

“遍历所有邮件,将符合标题的邮件附件下载到指定文件夹中,遍历打开的文件夹下的所有Excel文件,导入每个Excel表单的信息,将文件保存到Word模板中,保存到新文件夹中”

三、代码的实现

3.1确认消息-下载附件

首先完成第一部分的工作,然后阅读所有邮件。

Importkeyring

FromimboximportImbox

使用Keyring库,您可以通过系统密钥环在本地预先存储密码(验证码),以后在代码中调用keyring库方法,通过帐户将密码提取到变量中,从而降低密码(验证码)泄漏的可能性,从而通过imbox库获取附件。

password=keyring . get _ password(' yagmail ',' XXX @ 163.com ')

Withimbox ('imap.163.com ',' XXX @ 163.com ',password) ASI mbox 3360

all _ inbox _ messages=imbox . messages()

Foruid、message inall _ inbox _ messages 3360

Prin)

从需求可以看出,特定邮件以进修申请四个词开始,因此可以根据此收到特定邮件的附件。

password=keyring . get _ password(' yagmail ',' XXX @ 163.com ')

Withimbox ('imap.163.com ',' XXX @ 163.com ',password) ASI mbox 3360

all _ inbox _ messages=imbox . messages()

Foruid、message inall _ inbox _ messages 3360

Ifme[:4]='进修申请' :

   pass

pass 代码就可以写附件存储了。需要把 Excel 文件存储到指定文件夹中,因此需要先利用 os 库建立文件夹。邮件部分的代码如下:

import keyring from imbox import Imbox import os path = r'C:\xxx' if not os.(path + r'\申请表文件夹'):     os.mkdir(path + r'\申请表文件夹') password = keyring.get_password("yagmail","xxx@163.com") with Imbox('imap.163.com', 'xxx@163.com', password) as imbox:     all_inbox_messages = imbox.messages()     for uid, message in all_inbox_messages:         if me[:4] == '进修申请':               if me: # 判断是否存在附件                   for attachment in me:                       with open(path + f'\申请表文件夹\\{attachment["filename"]}', 'wb') as file:                           (attachment['content'].getvalue())

3.2 读取Excel —> 写入Word

接下来的操作涉及 Excel 读取和 Word 文件的写入,需要导入相应的模块。同时建立新文件夹存放最终的介绍信:

from docx import Document from openpyxl import load_workbook if not os.(path + r'\介绍信文件夹'):     os.mkdir(path + r'\介绍信文件夹')

现在 申请表文件夹 中存放 300 多个 Excel 文件,可以利用 glob 库进行遍历和读取:

import glob for file in glob.glob(path + r'\申请表文件夹\*.xlsx'):     workbook = load_workbook(file)     sheet = workbook.active

有效信息在第二行,列名(文本替换的依据)在第一行。但考虑到有的申请表可能不按常规,填写了多个人的申请,因此用循环,不局限在第二行:

for file in glob.glob(path + r'\申请表文件夹\*.xlsx'):     workbook = load_workbook(file)     sheet = workbook.active     for table_row in range(2,  + 1):  # 考虑到有的申请表可能不按常规,填写了多个人的申请,因此用循环         # 每循环一行实例化一个新的word文件         wordfile = Document(path + r'\新模板.docx')         # 单元格需要逐个遍历,每一个都包含着有用的信息         for table_col in range(1,  + 1):             # 旧的文本也就是列名,已经在模板里填好了,用于文本替换,将row限定在第一行后就是列名             old_text = '#' + str(row=1, column=table_col).value) + '#'             # 新的文本就是实际的信息,table_col循环到某个数值时,实际的单元格和列名就确定了             new_text = str(row=table_row, column=table_col).value)

获取到信息以后就可以进行 Word 模板文件的文本替换了,根据其 文档 Document - 段落 Paragraph - 文字块 Run的三级结构,在文字块层面完成替换:

# 文档Document - 段落Paragraph - 文字块Run         all_paragraphs = word         for paragraph in all_paragraphs:             for run in :                 run.text = run.(old_text, new_text)

介绍信的落款日期是当天的日期,可以考虑借助 datetime 库获取,并在替换新旧文本时同时判断 #今天日期# 这个文本是否存在,存在就替换为真实日期:

                run.text = run.(old_text, new_text)                 run.text = run.('#今天日期#', da())

最后保存即可,文件名中的姓名即为当前循环行的第一个单元格,(row=table_row,column=1).value

完整代码如下:

import keyring from imbox import Imbox from docx import Document from openpyxl import load_workbook import os import glob import datetime path = r'C:\xxx' if not os.(path + r'\申请表文件夹'):     os.mkdir(path + r'\申请表文件夹') password = keyring.get_password("yagmail", "xxx@163.com") with Imbox('imap.163.com', 'xxx@163.com', password) as imbox:     all_inbox_messages = imbox.messages()     for uid, message in all_inbox_messages:         if me[:4] == '进修申请':               if me:                   for attachment in me:                       with open(path + f'\申请表文件夹\\{attachment["filename"]}', 'wb') as file:                           (attachment['content'].getvalue()) if not os.(path + r'\介绍信文件夹'):     os.mkdir(path + r'\介绍信文件夹') for file in glob.glob(path + r'\申请表文件夹\*.xlsx'):     workbook = load_workbook(file)     sheet = workbook.active     for table_row in range(2,  + 1):  # 考虑到有的申请表可能不按常规,填写了多个人的申请,因此用循环         # 每循环一行实例化一个新的word文件         wordfile = Document(path + '\新模板.docx')         # 单元格需要逐个遍历,每一个都包含着有用的信息         for table_col in range(1,  + 1):             # 旧的文本也就是列名,已经在模板里填好了,用于文本替换,将row限定在第一行后就是列名             old_text = '#' + str(row=1, column=table_col).value) + '#'             # 新的文本就是实际的信息,table_col循环到某个数值时,实际的单元格和列名就确定了             new_text = str(row=table_row, column=table_col).value)             all_paragraphs = word             for paragraph in all_paragraphs:                 for run in :                     run.text = run.(old_text, new_text)                     run.text = run.('#今天日期#', da())         word(path + f'\\介绍信文件夹\\{(row=table_row,column=1).value} 进修介绍信.docx')

可以看到,整个复杂的需求就被瓦解成多个问题而成功解决!

关于作者: luda

无忧经验小编鲁达,内容侵删请Email至wohenlihai#qq.com(#改为@)

热门推荐