2023年1月12日 星期四

只要點兩下,就能寄送全校教職員薪資單 for Windows 10 x64



        總務處出納組每月都會在薪資入帳的當日,寄發全校教職員的薪資單。讓教職員可以核對入帳金額與薪資單金額。今天突然不能使用原本的一鍵寄送全校教職薪資單程式,而我也忘了該怎麼處理。就想到原本寫的1.只要點兩下,就能寄送全班個人成績單,可以用Python + Gmail 來批次寄送全校教職員薪資單。

        目前的狀況說明與解決方案如下:
1.薪資單不用另外製作,由原本的程式就可以批次產生。
但批次產生的資料夾名稱為Mail,在Mail資料夾內的批次產生的檔案名稱規則為PayList+入賬當日+"-"+員工編號,例如員工編號11003的人員在2023年01月12日當日入帳的薪資單名稱為PayList20230112-11003。
解決方案:
(1).在專案內,建立資料夾名稱Mail,Mail內有
PayList20230112-11003.txt、PayList20230112-11005.txt、PayList20230112-11007.txt、PayList20230112-11019.txt、PayList20230112-11021.txt、PayList20230112-11022.txt等6筆測試資料。
(2).針對資料夾Mail,讓Python讀取Mail內檔案名稱。

2.需整理出一個Excel檔案,其架構為 員工編號、員工姓名、員工電郵。
那設定該Excel檔案名稱為收件者資料.xlsx。
解決方案:
(1).在專案內,內建收件者資料.xlsx,內有如上圖等6筆資料。
(2).讓Python 讀取收件者資料.xlsx。

3.由於員工請育嬰留職停薪、侍親留職停薪、進修留職停薪等不發薪水情況。
換言之,不可依收件者資料來寄信,而要依薪資單檔案的有無,來決定是否寄發。
解決方案:
(1)刪除Mail內一筆資料,設定不發薪之情況。
(2)以Mail內檔案檔名為準,來核對收件者資料.xlsx

4.要保留信件標題與內文修改的權限。
換言之,要讓承辦人員可以依需要來修改信件標題與信件內文。
解決方案:
(1).內建信件標題.txt,讓Python讀取信件標題.txt。
(2).內建信件內文.txt,讓Python讀取信件內文.txt。

5.要考慮承辦人員的異動。
換言之,要讓承辦人員可以依需要來修改寄件者的電郵與密碼。
解決方案:
(1).內建寄件者電郵與密碼.txt,讓Python讀取寄件者電郵與密碼.txt。

6.最後要知道誰的電郵沒寄。
換言之,要讓承辦人員可以檢核未寄件者的資料。
解決方案:
(1).以Mail內檔案檔名為準,來核對收件者資料.xlsx。
(2).產出未寄信者資料.txt

       現在整理目前的狀況,以一張圖來呈現:

        最後完成程式:
下載檔案。解壓密碼:demo1234
教學影片:



        以下是使用教學,共有五個步驟:
一.若沒有Gmail,請先建立自己的Gmail
二.下載程式與解壓縮
三.設定寄件者電郵與密碼
四.對著01批次寄電郵給教職員_PythonGmail.exe點兩下
        
依序如下:
一.若沒有Gmail,請先建立自己的Gmail
        一次設定





二.下載程式與解壓縮
      解壓縮時,要注意:不能破壞資料夾結構。





.設定寄件者電郵與密碼
        一次設定
        程式預設使用Gmail。若沒有Gmail,請建立Gmail。
        設定兩步驟驗證


        設定 應用程式密碼




檔案名稱:PythonGmail.py
檔案內容:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
from email.mime.image import MIMEImage
from pathlib import Path
from email.mime.application import MIMEApplication
import os
import openpyxl as opxl

class EmailOpenFiles():
    #開啟檔案
   
    def __init__(self,DirectoryName,FileName):
        self.DirectoryName = DirectoryName
        self.FileName = FileName

    def AttachFiles(self):
        #取得附件資料夾內所有檔案名稱並回傳List
        AttachDirPath=str(os.path.abspath(os.getcwd()))+'\\'+self.DirectoryName+'\\'
        AttachFileNameList = os.listdir(AttachDirPath)
        return AttachFileNameList
   
    def EmailFileContent(self):
        #設定信件內容檔名並取得檔案內容並回傳List
        EmailContentFileName = str(os.path.abspath(os.getcwd()))+"\\"+self.FileName
        EmailContentFile = open(EmailContentFileName,'r')
        EmailContentList = EmailContentFile.readlines()
        EmailContentFile.close()
        return EmailContentList
   
    def AttachDirPath(self):
        #取得附件資料夾路徑
        AttachDirPath=str(os.path.abspath(os.getcwd()))+'\\'+self.DirectoryName+'\\'
        return AttachDirPath
   
    def AttachExcelOpen(self):
        #打開附件為Excel檔案並回傳List
        AttachExcelFileName = str(os.path.abspath(os.getcwd()))+"\\"+self.FileName
        TempExcelWorkBook = opxl.load_workbook(AttachExcelFileName)
        TempMax_Row = TempExcelWorkBook.worksheets[0].max_row
        TempMax_Column = TempExcelWorkBook.worksheets[0].max_column
        TempReturnList = []
        for i in range(1,TempMax_Row+1):
            TempList = []
            for j in range(1,TempMax_Column+1):
                TempList.append(TempExcelWorkBook.worksheets[0].cell(i,j).value)
            TempReturnList.append(TempList)
        return TempReturnList

class PythonGmail():
    def __init__(self,EmailSubject,EmailFrom,EmailTo,EmailContent,EmailAttachments,EmailSender,EmailPass):
        self.EmailSubject = EmailSubject
        self.EmailFrom = EmailFrom
        self.EmailTo = EmailTo
        self.EmailContent = EmailContent
        self.EmailAttachments = EmailAttachments
        self.EmailSender = EmailSender
        self.EmailPass = EmailPass
   
    def PythonGmail(self):
        #建立MIMEMMultipart物件
        content = MIMEMultipart()
        #郵件標題
        content["subject"] = self.EmailSubject
        #寄件者Email
        content["from"] = self.EmailFrom
        #收件者Email
        content["to"] = self.EmailTo
        #郵件內容
        content.attach(MIMEText(self.EmailContent))
       
        #附件寄送檔案
        AttachFileName = self.EmailAttachments
        AttachFileload = MIMEApplication(open(AttachFileName,'rb').read())
        AttachFileload.add_header('Content-Disposition','attachment',filename=AttachFileName)
        content.attach(AttachFileload)
       
        #設定SMTP伺服器
        with smtplib.SMTP(host="smtp.gmail.com",port="587") as smtp:
            try:
                #驗證SMTP伺服器
                smtp.ehlo()
                #建立加密傳輸
                smtp.starttls()
                #登入寄件者Gmail
                #smtp.login("寄件者信箱","寄件者密碼")
                smtp.login(self.EmailSender,self.EmailPass)
                #寄送郵件
                smtp.send_message(content)
                #顯示訊息
                return "Success! Send OK!"
            except Exception as e:
                return "Error message:"+str(e)

#取得附件資料夾內所有檔案名稱
EmailAttachments = EmailOpenFiles('Mail','').AttachFiles()
#取得附件資料夾的絕對路徑
EmailAttachDirPath = EmailOpenFiles('Mail','').AttachDirPath()

#取得信件標題檔案內容並存成信件標題list
EmailSubjectlist = EmailOpenFiles('','信件標題.txt').EmailFileContent()
#從信件標題list取得信件標題字串
EmailSubject = EmailSubjectlist[0]

#取得信件內容檔案內容並存成信件內容list
EmailContentlist = EmailOpenFiles('','信件內文.txt').EmailFileContent()
#從信件內容list取得信件內容字串
EmailContent = ""
for i in EmailContentlist:
    EmailContent = EmailContent + i

#從寄件者電郵與密碼.txt取得List
EmailSenderAddrList = EmailOpenFiles('','寄件者電郵與密碼.txt').EmailFileContent()
#去除List[0]標題
EmailSenderAddrList.pop(0)
#取得寄信者email與密碼
EmailSender,EmailPass = EmailSenderAddrList[0].split(',')

#從收件者資料.xlsx 取得List
EmailToList = EmailOpenFiles('','收件者資料.xlsx').AttachExcelOpen()
#去除List[0]標題
EmailToList.pop(0)
 
#未寄信者集合 tempSet
tempSet = set()
#依現有附件資料比對收件者資料,比對成功者逐一寄信
for i in EmailToList:
    A1,A2,A3 = i
    #將該員工編號加入未寄信者集合 tempSet
    tempSet.add(int(A1))
    for j in EmailAttachments:
        if int(A1) == int(j[-9:-4]):
            #EmailTest=PythonGmail(EmailSubject,EmailSender,A3,EmailContent,EmailAttachDirPath+j,EmailSender,EmailPass).PythonGmail()
            #print(str(A1)+" "+str(A2)+" Email "+ EmailTest)
            #將未寄信者集合tempSet移除該員工編號
            tempSet.remove(int(A1))

# 將未寄信者資料寫入 未寄信者資料.txt
OutFileName = '未寄信者資料.txt'
f = open(OutFileName,'w')
for i in tempSet:
    for j in EmailToList:
        A1,A2,A3 = j
        if int(i) == int(A1):
            print(str(A1)+"  "+str(A2)+"  "+str(A3),file=f)
f.close()

os.system("pause")
os.system("exit")




資料來源:





        

沒有留言:

張貼留言

Laravel 12 Model 資料庫中的資料表,並提供與資料庫互動的介面

相關系列文章: 1. 在 windows 10 安裝 laravel 12 studentManagement環境與設定 2. laravel 12 route 路由 3. laravel 12 Blade Templates 網頁模版 4. laravel 12 Control...