python 工資郵件羣發工具開發(一個小公司的需求)

------------------------------------

該需求有兩個表格,第一個表格是計算薪資的,第二個表格是員工信息,包括姓名和郵箱

這裏只要把薪資表按照每個人截圖放到一個文件夾中,從信息表取姓名和截圖名字做對應,然後發送郵件

 1、工資表樣式,名字必須和員工信息表一致

 

2、員工信息表樣式注意列,我沒有做行列自定義選擇的功能,現在是寫死的,當然也可以加個變量自定義

 

軟件樣式:

 

 

 

本程序是根據員工信息表的基礎,來判定是否成功發送郵件,如果工資表沒有這個人,那麼也沒有這個人的截圖,那這個人就未發送。

 授權碼就是qq郵箱的 第三方授權

 --------------------------------------------------

用到的包pillow 、xlwings、email、tkinter(界面UI)

-----------------------------------

這裏不多廢話,直接貼代碼

  1 from PIL import ImageGrab
  2 import xlwings as xw
  3 import smtplib
  4 from email.mime.multipart import MIMEMultipart
  5 from email.mime.text import MIMEText
  6 from email.mime.image import MIMEImage
  7 import tkinter as tk  # 使用Tkinter前需要先導入
  8 from tkinter import filedialog
  9 import os
 10 import time
 11 
 12 class Monitor():
 13     def __init__(self):
 14         #錯誤信息
 15         self.error = []
 16         self.nosend = []
 17         self.dictname =[]
 18 
 19     #判斷文件夾是否已經創建
 20     def is_exists(self,dir):
 21         if not os.path.exists(dir):
 22             os.makedirs(dir)
 23 
 24     # 截圖函數
 25     def excel_catch_screen(self,wbs,save_floder,shot_sheetname):
 26         sheet = wbs.sheets(shot_sheetname)  # 選定sheet
 27         all = sheet.used_range  # 獲取有內容的range
 28         all.api.CopyPicture()  # 複製圖片區域
 29         sheet.api.Paste()  # 粘貼
 30         pic = sheet.pictures[0]  # 當前圖片
 31         pic.api.Copy()  # 複製圖片
 32         img = ImageGrab.grabclipboard()  # 獲取剪貼板的圖片數據
 33         self.is_exists(save_floder)  # 判斷文件夾
 34         try:
 35             img.save(save_floder+'/'+shot_sheetname + ".png")  # 保存圖片
 36             pic.delete()  # 刪除sheet上的圖片
 37         except:
 38             print('%s 截圖失敗!'%shot_sheetname)
 39 
 40 
 41     #   郵件函數
 42     #   1、查看郵件excel中的所有對應值  (name,email)
 43     def get_info(self,dicts,info):
 44         app = xw.App(visible=False, add_book=False)
 45         wb = app.books.open(info)
 46         sheet = wb.sheets[0]
 47         maxrow = sheet.used_range.last_cell.row   # 最大行
 48         for row in range(2,maxrow+1):
 49             name = sheet.range('B' + str(row)).value
 50             email = str(sheet.range('J' + str(row)).value).replace('@qq.com','')
 51             dicts[name] = email.replace('.0','')+'@qq.com'
 52         wb.close()
 53         app.quit()
 54     #2、發送郵件
 55     def send_png(self,subject,sender,name,receivers,password,png):
 56         message = MIMEMultipart('related')
 57         message['Subject'] = subject
 58         message['From'] = sender
 59         message['To'] = receivers
 60         content = MIMEText('<html><body><img src="cid:imageid" alt="imageid"></body></html>','html','utf-8')
 61         message.attach(content)
 62         file=open(png, "rb")
 63         img_data = file.read()
 64         file.close()
 65         img = MIMEImage(img_data)
 66         img.add_header('Content-ID', 'imageid')
 67         message.attach(img)
 68         try:
 69             server=smtplib.SMTP_SSL("smtp.qq.com",465)
 70             server.login(sender,password) #"填寫qq郵箱的授權碼"
 71             server.sendmail(sender,receivers,message.as_string())
 72             server.quit()
 73             print ("郵件發送成功")
 74         except smtplib.SMTPException as e:
 75             self.error.append(name)
 76             pass
 77 
 78     def work(self,subject,sender,password,excel_name,info_name):
 79         sheetname=[]
 80         app = xw.App(visible=False, add_book=False)
 81         wb = app.books.open(excel_name)
 82         num = len(wb.sheets)
 83         #用sheetname 接受所有員工的sheet名
 84         for i in range(1,num):
 85             sheet = wb.sheets[i]
 86             sheetname.append(sheet.name)
 87         #循環截屏並保存到自定義文件夾下
 88         save_floder = './'+subject
 89         for name in sheetname:
 90             self.excel_catch_screen(wb,save_floder,name)
 91             time.sleep(5)
 92         #存儲員工信息表
 93         dicts = {}
 94         self.get_info(dicts,info_name)
 95 
 96         wb.close()  # 不保存,直接關閉
 97         app.quit()
 98         #循環發送郵件 #發送郵件 根據excel中的郵件人姓名和地址進行匹配已保存的png圖片,順序發送
 99         # 遍歷字典,在文件夾中找對應圖片
100         for name, receivers in dicts.items():
101             self.dictname.append(name)
102         for file in os.listdir(save_floder):
103             self.nosend.append(file.replace('.png',''))
104         for name, receivers in dicts.items():
105             if name in self.nosend:
106                 self.send_png(subject,sender,name,receivers,password,save_floder+'/'+name+'.png')
107                 print(sender,receivers,name,save_floder+'/'+name+'.png')
108             else:
109                 self.error.append(name)
110 
111     def main(self):
112         # password = 'zbtwghtciidmbaii'
113         # 界面化處理
114         window = tk.Tk()
115         window.title('郵件羣發V1.0')
116         # 第3步,設定窗口的大小(長 * 寬)
117         window.geometry('400x400')  # 這裏的乘是小x
118 
119         def selectPath():
120             entry_excel_name = filedialog.askopenfilename(title='選擇工資計算表',
121                       initialdir='/', filetypes=[('.xlsx','*.xlsx'),('全部文件','*.*')])
122             return entry_excel_name
123         def selectPath1():
124             entry_info_name = filedialog.askopenfilename(title='選擇員工信息表',
125                       initialdir='/', filetypes=[('.xlsx','*.xlsx'),('全部文件','*.*')])
126             return entry_info_name
127 
128         def exec(entry_excel_name,entry_info_name):
129             try:
130                 subject = entry_title.get()
131                 sender = entry_usr_name.get()
132                 password = entry_usr_pwd.get()
133                 excel_name = entry_excel_name
134                 info_name = entry_info_name
135 
136                 self.work(subject,sender,password,excel_name,info_name)
137                 if len(self.error) == 0:
138                     text.insert('insert','所有郵件發送成功')
139                 else:
140                     text.insert('insert','%s 郵件發送失敗' % self.error)
141 
142             except Exception as e:
143                 if e == 'No such file: ':
144                     text.insert('insert','沒有選擇文件')
145                 else:
146                     text.insert('insert',e)
147 
148 
149         # 用戶信息
150         tk.Label(window, text='郵件標題:', font=('Arial', 10)).place(x=10, y=5)
151         tk.Label(window, text='Q Q 號:', font=('Arial', 10)).place(x=10, y=35)
152         tk.Label(window, text='授權碼:', font=('Arial', 10)).place(x=10, y=65)
153 
154         subject = tk.StringVar()
155         subject.set('XX年XX月薪資')
156         entry_title = tk.Entry(window, textvariable=subject, font=('Arial', 10))
157         entry_title.place(x=120, y=5)
158 
159         var_usr_name = tk.StringVar()
160         var_usr_name.set('[email protected]')
161         entry_usr_name = tk.Entry(window, textvariable=var_usr_name, font=('Arial', 10))
162         entry_usr_name.place(x=120, y=35)
163 
164         var_usr_pwd = tk.StringVar()
165         entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, font=('Arial', 10), show='*')
166         entry_usr_pwd.place(x=120, y=65)
167 
168         #程序運行框
169         text = tk.Text(window, show=None)
170         text.place(relx=0.01,rely=0.3,relwidth=0.98,relheight=0.7)
171 
172         # 執行按鈕
173         btn_login = tk.Button(window, text='立即執行',height = 4,  width = 15 ,command= lambda : exec(selectPath(),selectPath1()))
174         btn_login.place(x=275, y=6)
175 
176         # 主窗口循環顯示
177         window.mainloop()
178 
179 if __name__ == '__main__':
180     app = Monitor()
181     app.main()
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章