1、文件说明
源代码下载
链接:https://pan.baidu.com/s/1fCFVOrYkIVq33p1IswQe_A
提取码:QHQH
2、界面介绍
3、主要代码展示
a、邮件功能代码
# -*- coding: UTF-8 -*-
import smtplib
from email.mime.text import MIMEText
import email.mime.multipart
import email.mime.text
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import QhEamilSeting
def QhLoginEmail(qh_smtpserver,qh_port, qh_from_email, qh_psw):
"""
登录邮箱 作者:阙辉
:param qh_smtpserver: 邮箱服务器
:param qh_port: 邮箱端口
:param qh_from_email: 发送邮箱
:param qh_psw: 发送邮箱授权码
:return:
"""
try:
# qh_smtp = smtplib.SMTP() # 实例化邮件对象
# qh_smtp.connect(qh_smtpserver) # 链接服务器
# qh_smtp.login(qh_from_email, qh_psw) # 登录
qh_smtp = smtplib.SMTP_SSL(qh_smtpserver, qh_port) # 实例化一个SMTP_SSL对象
QhloginRes = qh_smtp.login(qh_from_email, qh_psw) # 登录smtp服务器
if QhloginRes and QhloginRes[0] == 235:
print(f"登录成功QH,code = {QhloginRes[0]}")
else:
print(f"登陆失败QH,code = {QhloginRes[0]}")
return qh_smtp
except Exception as e:
print(f"登录失败QH,Exception: e={e}")
def QhSendEmail(qh_smtp, qh_from_email, qh_to_email,qh_cc_emil="",
qh_body="", qh_zhuti="",qh_fj_path = "",qh_fj_name = ""):
"""
邮件自动发送方法 作者:阙辉
:param qh_smtp:邮件对象
:param qh_body:邮件内容
:param qh_from_email:发件人邮箱
:param qh_to_email:收件人邮箱
:param qh_zhuti:邮件主题
:param qh_fj_path: 附件路径
:param qh_fj_name: 附件名称
:return:
"""
qh_msg = email.mime.multipart.MIMEMultipart()
qh_msg['from'] = qh_from_email
qh_msg['to'] = qh_to_email
qh_msg['subject'] = qh_zhuti
#抄送邮箱
if qh_cc_emil != "":
qh_msg['Cc'] = qh_cc_emil
qh_to_email = str(qh_to_email) + ';' + str(qh_cc_emil)
# 邮件内容
qh_body_e = MIMEText(qh_body, 'html', 'utf-8')
qh_msg.attach(qh_body_e)
# 邮件附件 可以有多个附件 也可以单个附件
if qh_fj_path != "":
qh_fj_name = qh_fj_name.split(",")
if not isinstance(qh_fj_name,list):
qh_fj_name = [qh_fj_name]
for qh_row in qh_fj_name:
qh_fj_path_name = qh_fj_path + "\\" + qh_row
try:
qh_part = MIMEApplication(open(qh_fj_path_name, 'rb').read())
except Exception as e:
print(f"附件问题QH,Exception: e={e}")
qh_part.add_header('Content-Disposition', 'attachment', filename=qh_row) # 发送文件名称
qh_msg.attach(qh_part)
try:
qh_smtp.sendmail(qh_from_email, qh_to_email.split(";"), qh_msg.as_string())
qh_smtp.quit() # 退出邮箱
print("发送成功QH")
except Exception as e:
qh_smtp.quit() # 退出邮箱
print(f"发送失败QH,Exception: e={e}")
if __name__ == "__main__":
QhEamilSeting = QhEamilSeting.QhEamilSeting # 获取发件人参数
qh_smtpserver = QhEamilSeting['qh_smtpserver'] # 发件服务器
qh_port = QhEamilSeting['qh_port'] # 端口
qh_from_email = QhEamilSeting['qh_sender'] # 发件人邮箱
qh_psw = QhEamilSeting['qh_psw'] # 发件人授权码
qh_to_email = '305879921@qq.com;mary@catch-scm.com' # 收件人邮箱
qh_cc_emil = '1476239572@qq.com;odjango@163.com' # 抄送人
qh_zhuti = "测试python自动邮件" # 邮件主题
qh_body_m = '''<p>{}</p>
<p>_____________________________________________________</p>
<p>{}</p>
'''
qh_body = "你好阙辉!测试发送!" # 邮件内容
qh_body = qh_body_m.format(qh_body,qh_from_email)
qh_fj_path = r"C:\Users\QH\Desktop" #附件路径
qh_fj_name = "测试附件.xlsx,测试附件.xlsx,测试附件.xlsx" #附件名称 注意要带后缀名
# qh_smtp = smtplib.SMTP() # 实例化邮件对象
# qh_smtp.connect(qh_smtpserver) # 链接服务器
# qh_smtp.login(qh_from_email, qh_psw) # 登录
qh_smtp = QhLoginEmail(qh_smtpserver,qh_port, qh_from_email, qh_psw)
QhSendEmail(qh_smtp, qh_from_email, qh_to_email,
qh_cc_emil=qh_cc_emil, qh_body=qh_body, qh_zhuti=qh_zhuti,
qh_fj_path=qh_fj_path, qh_fj_name=qh_fj_name) # 发送邮件
b、前端逻辑代码
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import pyqtSlot, Qt, QPoint,QCoreApplication
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QFileDialog
import os
import pandas as qh_pd
import QhSendEmail as qh_se
import QhEamilSeting as qh_es
from PyQt5.QtWidgets import QMessageBox
import QhEmailGUIView as QhView
class Qh_Web_Widget(QWidget,QhView.Ui_Form):
# 用的是多继承
def __init__(self,qh_parent = None):
super().__init__(qh_parent)
self.setupUi(self) # 调用Qh_SetupUI()函数,并把窗口作为实参传递给Qh_Set/upUI()函数
# self.widget.setUrl(QtCore.QUrl("https://passtc.sf-express.com/ucenter/userlogin?platform=TC-FIN|NDcy&return_url=http%3A%2F%2Fcastc.sf-express.com%2Fcas%2Fcallbackbypass%3Fplatform%3DTC-FIN%7CNDcy&redirect_url=http://tcfin.sf-express.com/ierp/index.html"))
# self.widget.page().profile().downloadRequested.connect(self._downloadRequested)
self._QhGetSetting()
self._QH_init_main_window()
self._Qh_XinHaoAndSolt()
def _Qh_XinHaoAndSolt(self):
self.QhFormClose.clicked.connect(self.close)
# self.QhFormMax.clicked.connect(self.QhFormMax_Min)
self.QhFormMin.clicked.connect( self.showMinimized)
self.QhSendBUT.clicked.connect(self.QhSendEamil)
self.QhExcelFileNameBut.clicked.connect(self.QhOpenExcelPath)
self.QhFuJianPathBut.clicked.connect(self.QhOpenFjPath)
self.QhCanShuSaveBUT.clicked.connect(self.QhSaveCanShu)
def mousePressEvent(self, evt):
"""
# 1.鼠标点击事件
:param evt:
:return:
"""
if not self.isMaximized():
# 如果已经是最大化,则不再获取鼠标位置 阙辉
# 获取鼠标当前的坐标
self.mouse_x = evt.globalX()
self.mouse_y = evt.globalY()
# 获取窗体当前坐标
self.origin_x = self.x()
self.origin_y = self.y()
def mouseMoveEvent(self, evt):
"""
# 2.鼠标移动事件
:param evt:
:return:
"""
if not self.isMaximized():
# 如果已经是最大化,则不能再移动 阙辉
# 计算鼠标移动的x,y位移
move_x = evt.globalX() - self.mouse_x
move_y = evt.globalY() - self.mouse_y
# 计算窗体更新后的坐标:更新后的坐标 = 原本的坐标 + 鼠标的位移
dest_x = self.origin_x + move_x
dest_y = self.origin_y + move_y
# 移动窗体
self.move(dest_x, dest_y)
def _QH_init_main_window(self):
# 设置窗体无边框
self.setWindowFlags(Qt.FramelessWindowHint)
# 设置背景透明
# self.setAttribute(Qt.WA_TranslucentBackground)
def _QhGetSetting(self):
self.QhEamilSeting = qh_es.QhEamilSeting # 获取发件人参数
QhEamilSeting = self.QhEamilSeting
qh_smtpserver = QhEamilSeting['qh_smtpserver'] # 发件服务器
qh_port = QhEamilSeting['qh_port'] # 端口
qh_from_email = QhEamilSeting['qh_sender'] # 发件人邮箱
qh_psw = QhEamilSeting['qh_psw'] # 发件人授权码
qh_csr = QhEamilSeting['qh_csr'] # 抄送人邮箱
qh_excel = QhEamilSeting['qh_excel'] # 默认excel名
qh_excelsheet = QhEamilSeting['qh_excelsheet'] # 默认excelsheet名
qh_fujianfile = QhEamilSeting['qh_fujianfile'] # 默认附件文件夹名
qh_path = os.path.dirname(__file__) # 当前文件所在路径
qh_excel_path = os.path.join(qh_path, qh_excel)
qh_fujianfile_path = os.path.join(qh_path, qh_fujianfile) # 指定附件文件夹
self.QhEamilSeverLine.setText(str(qh_smtpserver))
self.QhEamilProtLine.setText(str(qh_port))
self.QhSendEmailLine.setText(str(qh_from_email))
self.QhEmailPaswdLine.setText(str(qh_psw))
self.QhChaoSongText.setText(str(qh_csr))
self.QhExcelFileNameLine.setText(str(qh_excel_path))
self.QhExcelFileSheetNameLine.setText(str(qh_excelsheet))
self.QhFuJianPathLine.setText(str(qh_fujianfile_path))
def QhOpenExcelPath(self):
"""
# 选取excel 路径
:return:
"""
qh_excel_path, ok1 = QFileDialog.getOpenFileName(self,
"多文件选择",
"./",
"All Files (*);;Text Files (*.txt)")
# qh_excel_path = files
self.QhExcelFileNameLine.setText(str(qh_excel_path))
def QhOpenFjPath(self):
"""
指定附件路径
:return:
"""
qh_fujianfile_path = QFileDialog.getExistingDirectory(self,
"选取文件夹",
"./") # 起始路径
self.QhFuJianPathLine.setText(str(qh_fujianfile_path))
def QhSaveCanShu(self):
qh_smtpserver = self.QhEamilSeverLine.text() # 发件服务器
qh_port = int(self.QhEamilProtLine.text()) # 端口
qh_from_email = self.QhSendEmailLine.text() # 发件人邮箱
qh_psw = self.QhEmailPaswdLine.text() # 发件人授权码
qh_csr = self.QhChaoSongText.toPlainText() # 抄送人邮箱
qh_excel = self.QhExcelFileNameLine.text() # 默认excel名 带路径
qh_excelsheet = self.QhExcelFileSheetNameLine.text() # 默认excelsheet名
qh_fujianfile_path = self.QhFuJianPathLine.text() # 默认附件文件夹名
qh_excel1 = str(qh_excel).split("\\")[-1] #切割excel名
qh_fujianfile_path1 = str(qh_fujianfile_path).split("\\")[-1] #切割附件路径
QhEamilSeting = {
'qh_smtpserver': qh_smtpserver, # 发件服务器
'qh_port': qh_port, # 端口
'qh_sender': qh_from_email, # 发件人邮箱
'qh_psw': qh_psw, # 发件人授权码
'qh_csr': qh_csr, # 抄送人邮箱
'qh_excel':qh_excel1, # 默认excel名
'qh_excelsheet': qh_excelsheet, # 默认excelsheet名
'qh_fujianfile': qh_fujianfile_path1, # 默认附件文件夹名
}
qh_app_sett_json = "QhEamilSeting = {}"
qh_app_sett_json = qh_app_sett_json.format(str(QhEamilSeting))
qh_py_path = "QhEamilSeting.py"
f = open(qh_py_path, "w")
f.write("# encoding:gbk\n# 作者:阙辉\n")
f.write(qh_app_sett_json)
f.close()
QhEamilSeting["qh_psw"] = "********"
QMessageBox.information(self, "提示_QH", "{}参数保存成功,QH!".format(QhEamilSeting), QMessageBox.Ok)
def QhSendEamil(self):
qh_smtpserver = self.QhEamilSeverLine.text() # 发件服务器
qh_port = int(self.QhEamilProtLine.text()) # 端口
qh_from_email = self.QhSendEmailLine.text() # 发件人邮箱
qh_psw = self.QhEmailPaswdLine.text() # 发件人授权码
qh_csr = self.QhChaoSongText.toPlainText() # 抄送人邮箱
qh_excel = self.QhExcelFileNameLine.text() # 默认excel名 带路径
qh_excelsheet = self.QhExcelFileSheetNameLine.text() # 默认excelsheet名
qh_fujianfile_path = self.QhFuJianPathLine.text() # 默认附件文件夹名
if not self.QhYanChongCheckBox.isChecked():
self.QhYanChongCheckBox.setChecked(True)
#发送邮件逻辑
qh_td_pd = qh_pd.read_excel(io=qh_excel, sheet_name=qh_excelsheet)
qh_i = 0
for qh_ind, qh_row in qh_td_pd.iterrows():
if qh_row['提单号'] != "":
qh_danhao = qh_td_pd.iloc[qh_i]['提单号'] # 单号 附件文件夹名称要和单号一致
print("正在处理提单号({})邮件QH".format(qh_danhao))
qh_path_e = os.path.join(qh_fujianfile_path, str(qh_danhao))
qh_fj_name = ""
try:
for qh_filename_row in os.listdir(qh_path_e):
qh_fj_name = str(qh_fj_name) + str(qh_filename_row) + ","
qh_fj_name = qh_fj_name[:-1] # 附件名称 注意要带后缀名
except Exception as e:
print(f"附件问题QH,Exception: e={e}")
continue
print(qh_fj_name)
qh_to_email = qh_row['收件人'] # 收件人邮箱
qh_cc_emil = qh_csr # 抄送人
qh_zhuti = str(qh_row['邮件主题']) # 邮件主题
qh_body_m = '''<p>{}</p>
<p>_____________________________________________________</p>
<p>{}</p>
'''
qh_body = str(qh_row['邮件内容']) # 邮件内容 邮件内容
qh_body = qh_body_m.format(qh_body, qh_from_email) # 添加签名
qh_fj_path = qh_path_e # 附件路径
# qh_fj_name = "测试附件.xlsx,测试附件.xlsx,测试附件.xlsx" # 附件名称 注意要带后缀名
qh_smtp = qh_se.QhLoginEmail(qh_smtpserver, qh_port, qh_from_email, qh_psw)
qh_se.QhSendEmail(qh_smtp, qh_from_email, qh_to_email,
qh_cc_emil=qh_cc_emil, qh_body=qh_body, qh_zhuti=qh_zhuti,
qh_fj_path=qh_fj_path, qh_fj_name=qh_fj_name) # 发送邮件
qh_i += 1
else:
QMessageBox.information(self, "提示_QH", "该批邮件已发送,如需重新发送请去勾,QH!", QMessageBox.Ok)