用Python实现Excel内合同到期前,发送邮件提醒
工作中经常碰到会有财务同事有一个合同台账的Excel表格,定期在合同到期前她们会发个提醒邮件给你,他们在想如果能做到自动提醒就好了,于是我用Python写了段代码,帮助他们实现这个功能。
下面这个是Excel的内容例子:
***这段代码可以用于excel表格中合同到期前每隔30天,60天,90天,自动调用outlook发送邮件提醒的功能,其他类似于提醒的功能也可以使用,有如下问题需要注意:
1.准备做成选择路径的方式,目前还不行。
2.Excel的每个sheet的H、L和M列不能删除或移动,L列“Today”和M“距离到期日天数”里面有公式取值,不要修改,H列“合同终止日期”的内容可以根据需要修改。
3.Excel中sheet的合同可以新增,但是需要符合上述的格式
4.可以增加sheet,或者修改sheet的名字
5.程序运行时因为要调用outlook,所以请同时在本地登录outlook邮箱
6.config.txt文件内存放收件人的邮箱地址,用分号“;”隔开
7.config.txt,autosendmail.exe,合同台账.xlsx三个文件需要放在同一个目录下
8.可以编译成exe文件运行
9.可以使用计划任务设置每天定时运行***
具体代码如下:
# -*- coding: utf-8 -*-
"""
Module 合同到期前,发送邮件提醒,避免遗漏处理
"""
import os
import xlrd #读取xlsx
import win32com.client as win32 #调用outlook
import openpyxl #写入xlsx
from datetime import datetime
from win32com.client import Dispatch #读取excel公式
def main():
sNow = datetime.now().date() #获取当天的日期
todayToexcel(sNow)
just_open(filePath())
wb = xlrd.open_workbook(filename=filePath()) #打开excel
sheetNumbers = len(wb.sheet_names()) #获取sheet的数量
for j in range(0, sheetNumbers):
sheet1 = wb.sheet_by_index(j)
nrows1 = sheet1.nrows #获取行数
for iRow in range(1, nrows1):
sCheck = sheet1.cell(iRow, 12).value #获取指定单元格数据
if sCheck == 90:
s2 = sheet1.cell(iRow, 2).value
sendEmail(s2) #发送邮件
elif sCheck == 60:
s2 = sheet1.cell(iRow, 2).value
sendEmail(s2)
elif sCheck == 30:
s2 = sheet1.cell(iRow, 2).value
sendEmail(s2)
def sendEmail(sTask):
try:
#读取config.txt,获得发送的目标邮箱账号
sConfigFile = "config.txt"
f = open(sConfigFile, 'r')
try:
file_Context = f.read()
except:
return False
finally:
if f:
f.close()
outlook = win32.Dispatch('outlook.application') #调用函数
mail = outlook.CreateItem(0) #打开outlook
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()
return True
except Exception as e:
return False
def todayToexcel(today):
#从datetime函数读取
wb = openpyxl.load_workbook(filePath()) #打开文件
sheetNumber = len(wb.sheetnames) #获得sheet的数量
for j in range(0, sheetNumber):
outSheet = wb.worksheets[j] #定位到相应的sheet,[j]为sheet页索引
nRows = outSheet.max_row #获取行数
for i in range(2, nRows+1):
outSheet.cell(row=i, column=12).value = today
wb.save(filePath())
def filePath():
#读取excel文件的路径
sPath = os.getcwd() #获取当前路径
sFile = "合同台账.xlsx" #文件名
sExcelFile = sPath + "\\" + sFile #拼接完整路径
return sExcelFile
def just_open(filename):
#该函数用于读取excel中的公式结果,解决xlrd读取公式单元格内容为空的问题
xlApp = Dispatch("Excel.Application")
xlApp.Visible = False
xlBook = xlApp.Workbooks.Open(filename)
xlBook.Save()
xlBook.Close()
if __name__ == '__main__':
main()