前言
在工作中,有时会有一些定期需要执行的任务或在将来某一天需要执行的任务,为避免疏漏,设计个小工具,发邮件提醒自己去处理.
方案简介
1.建立一个Excel文件,里面定义好待提醒的任务
2.建立一个记事本文件,里面输入待接收邮件的邮箱账号
3.采用Python编写代码,读取Excel文件,检查是否该发送提醒邮件,如果需要提醒,则发出邮件给接收人。
4.把python编写的代码,打包成exe可执行文件
5.采用Windows的定时任务作业,调度打包好的exe文件
适用环境:
1.Windows平台
2.已经配置好可以收发邮件的Outlook
详细方案:
1.Excel名称:Task.xlsx,sheet名:sheet1
说明:
1)、Frequency列,执行频率
2)、Item列,分如下三种情况
a.当Frequency为Week,Item为Monday,表明周一需要执行,Item可填写的内容为英文星期
b.当Frequency为Month,Item为1-30中间的某个数值,在当月那一天执行
c.当Frequency为Day,Item为具体日期,表明到了指定日期,发出提醒邮件,注意填写的日期格式:yyyy-mm-dd
Item这一列,设置为文本格式
3)、Task为发送邮件的提醒内容
4)、是否处理,如果为Y ,则表明已经处理过了,无需再发提醒邮件
2.记事本,config.txt,里面填写待接收邮件的邮箱账号,如果是多个人,则邮箱账号间用分号分开
3.Python代码
调用Outlook发送邮件,调用Outlook发送邮件,有两种方式:
一是知道邮箱服务器的smtp服务器地址,并有一个邮箱账号和口令,在代码里设置登陆邮箱,发出邮件。
二是单位的电脑已经配置好了,outlook可以直接使用,不知道smtp服务器的地址,而且无法登陆第三方的邮箱系统发送邮件,比如无法通过登陆smtp.163.com,
这种情况下,只能调用本电脑上的outlook。
这里采用第二种方式,参考代码如下:
#-*- coding: utf-8 -*-
"""Module 根据定义的Task,发送邮件提醒,避免遗漏处理"""
importosimportxlrdimportscheduleimporttimeimportwin32com.client as win32from datetime importdatetime,date
dictWeek={0:"Monday",1:"TuesDay",2:"Wednesday",3:"Thursday",4:"Friday",5:"Saturday",6:"Sunday"}defmain():
sPath=os.getcwd()
sFile= "Task.xlsx"sExcelFile= sPath +"\\" +sFile
wb= xlrd.open_workbook(filename=sExcelFile)
sheet1=wb.sheet_by_index(0)
nrows1=sheet1.nrows#注意weekday() 返回的是0-6是星期一到星期日
sWeekday =dictWeek.get(datetime.now().weekday())
sNow=datetime.now()
iDay=sNow.day
sToday= formatDay(sNow,"yyyy-mm-dd")for iRow in range(1,nrows1):
sCheck= sheet1.cell(iRow,3).valueif sCheck != "Y":
sFrequency=sheet1.cell(iRow,0).value
s1= sheet1.cell(iRow,1).valueif sFrequency == "Week":if s1 ==sWeekday:
s2= sheet1.cell(iRow,2).value
sendEmail(s2)elif sFrequency == "Day":if s1 ==sToday:
s2= sheet1.cell(iRow,2).value
sendEmail(s2)elif sFrequency == "Month":if int(s1) ==int(iDay):
s2= sheet1.cell(iRow,2).value
sendEmail(s2)defformatDay(sDay,sFormat):
sYear=str(sDay.year)
sMonth=str(sDay.month)
sDay=str(sDay.day)if sFormat == "yyyy-mm-dd":
sFormatDay= sYear +"-" +sMonth.zfill(2)+"-" +sDay.zfill(2)elif sFormatStyle == "yyyy/mm/dd":
sFormatDay= sYear +"/" +sMonth.zfill(2)+"/" +sDay.zfill(2)else:
sFormatDay= sYear+"-" + sMonth + "-" +sDayreturnsFormatDaydefsendEmail(sTask):try:#读取config.txt,获得发送的目标邮箱账号
sConfigFile="config.txt"f=open(sConfigFile,'r')try:
file_Context=f.read()except:returnFalsefinally:iff:
f.close()
outlook= win32.Dispatch('outlook.application')
mail=outlook.CreateItem(0)
receivers=[file_Context]
mail.To=receivers[0]
mail.Subject='这是一封提醒邮件.'mail.Body="邮件提醒: \r\n 请注意处理任务作业,如已处理可忽略此封邮件。\r\n 任务内容:" + sTask + "\r\n (此邮件由系统自动发送)"
#mail.Attachments.Add('C:\\Users\enegc\\OneDrive - Bayer\\Personal Data\\'+sFileName+'.xlsx')
mail.Send()returnTrueexceptexceptions as e:returnFalseif __name__ == "__main__":
main()
4.打包Python文件成exe文件,使用pyinstaller
pyinstaller -F -w AutoSendEmail.py
5.部署,把打包好的exe文件从第4步生成的dist文件里拷贝出来,和config.txt以及Task.xlsx文件放到同一个文件夹里,然后在Windows的任务作业里建立一个任务作业,调用
打包好的exe文件,设置成每天执行。
6.上面部署的方式,是利用Windows的定时任务作业调用打包好的exe文件,也可以采用Python自己的任务调度方式,打包成exe后,双击启动,驻留在内存中,由系统自动调用
任务作业。
示例代码如下,这里设置的是每天10:30执行
#-*- coding: utf-8 -*-
"""Module 根据定义的Task,发送邮件提醒,避免遗漏处理"""
importosimportxlrdimportscheduleimporttimeimportwin32com.client as win32from datetime importdatetime,date
dictWeek={0:"Monday",1:"TuesDay",2:"Wednesday",3:"Thursday",4:"Friday",5:"Saturday",6:"Sunday"}defjob():
sPath=os.getcwd()
sFile= "Task.xlsx"sExcelFile= sPath +"\\" +sFileprint("Test")
wb= xlrd.open_workbook(filename=sExcelFile)
sheet1=wb.sheet_by_index(0)
nrows1=sheet1.nrows#注意weekday() 返回的是0-6是星期一到星期日
sWeekday =dictWeek.get(datetime.now().weekday())
sNow=datetime.now()
iDay=sNow.day
sToday= formatDay(sNow,"yyyy-mm-dd")for iRow in range(1,nrows1):
sCheck= sheet1.cell(iRow,3).valueif sCheck != "Y":
sFrequency=sheet1.cell(iRow,0).value
s1= sheet1.cell(iRow,1).valueif sFrequency == "Week":if s1 ==sWeekday:
s2= sheet1.cell(iRow,2).value
sendEmail(s2)elif sFrequency == "Day":if s1 ==sToday:
s2= sheet1.cell(iRow,2).value
sendEmail(s2)elif sFrequency == "Month":if int(s1) ==int(iDay):
s2= sheet1.cell(iRow,2).value
sendEmail(s2)defformatDay(sDay,sFormat):
sYear=str(sDay.year)
sMonth=str(sDay.month)
sDay=str(sDay.day)if sFormat == "yyyy-mm-dd":
sFormatDay= sYear +"-" +sMonth.zfill(2)+"-" +sDay.zfill(2)elif sFormatStyle == "yyyy/mm/dd":
sFormatDay= sYear +"/" +sMonth.zfill(2)+"/" +sDay.zfill(2)else:
sFormatDay= sYear+"-" + sMonth + "-" +sDayreturnsFormatDaydefsendEmail(sTask):try:#读取config.txt,获得发送的目标邮箱账号
sConfigFile="config.txt"f=open(sConfigFile,'r')try:
file_Context=f.read()except:returnFalsefinally:iff:
f.close()
outlook= win32.Dispatch('outlook.application')
mail=outlook.CreateItem(0)
receivers=[file_Context]
mail.To=receivers[0]
mail.Subject='这是一封提醒邮件.'mail.Body="邮件提醒: \r\n 请注意处理任务作业,如已处理可忽略此封邮件。\r\n 任务内容:" + sTask + "\r\n (此邮件由系统自动发送)"
#mail.Attachments.Add('C:\\Users\enegc\\OneDrive - Bayer\\Personal Data\\'+sFileName+'.xlsx')
mail.Send()returnTrueexceptexceptions as e:returnFalse
schedule.every().day.at("10:30").do(job)whileTrue:
schedule.run_pending()
time.sleep(1)
代码参考,已分享在百度网盘上。
链接:https://pan.baidu.com/s/1KMKVmpEyuA3zI0lEhfon7A
提取码:dzi9
日期:2019-07-03