Python批量发送带附件的邮件,软件设计

一.软件功能

        邮件批量发送软件可以模拟手动发送过程,实现邮件的批量发送,节省工作量,提高工作效率。

二.代码实现

        代码分两部分,软件界面设计及功能函数设计。

        2.1 界面设计

        界面用pyqt5进行设计,分为两部分:发送设置与内容设置。

        2.2 功能实现

        功能部分主要包括界面内容的读取与邮件发送。

        界面读取包括从界面部分读取相应的用户名、授权码、发送间隔等信息。

        邮件发送分为创建实例、添加邮件文字部分、添加邮件附件部分。

    def send_functtion(self, receivers):

        msg = MIMEMultipart()  # 创建一个带附件的实例
        msg["Subject"] = mail_subject
        msg["From"] = mail_user
        msg["To"] = ','.join([receivers])

        # ---文字部分---
        part = MIMEText(mail_text)
        msg.attach(part)

        # ---附件部分---
        part = MIMEApplication(open(mail_txt_add, 'rb').read())
        part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(mail_txt_add))
        msg.attach(part)

        try:
            s = smtplib.SMTP(mail_smtp, timeout=(mail_span_time*len(receiver_list)+1000))  # 连接smtp邮件服务器,端口默认是25;超时时间设置大一点
            s.login(mail_user, mail_pass)  # 登陆服务器
            s.sendmail(mail_user, receivers, msg.as_string())  # 发送邮件
            s.close()
        except Exception as e:
            print("error:", e)

三.软件使用及注意事项

        3.1 软件使用方法

        使用时,在发送设置中输入邮箱用户名、SMTP授权码、发送间隔,选择存放目标邮件地址的txt文件。
        SMTP授权码获取方法可以自行百度。

        内容设置中输入邮件主题、正文,选择邮件的附件。
        设置完成后点击“发送”按钮,提示窗中显示发送进度具体内容,下方显示发送进度条。

        3.2 软件注意事项
        (1)存放目标邮件地址的txt文件中:不同邮件地址需以“,”(英文)隔开,且除了地址和逗号外不能存在其他内容,如回车等;
        (2)邮件的附件只能选择一个,适用于txt、word、pdf类型的文件,其他文件不宜超过500KB,其余情况请自行测试。
      

附录:代码源码

界面代码

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'windows_screen.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(819, 625)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.user_label = QtWidgets.QLabel(self.centralwidget)
        self.user_label.setGeometry(QtCore.QRect(40, 86, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.user_label.setFont(font)
        self.user_label.setObjectName("user_label")
        self.user_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.user_lineEdit.setGeometry(QtCore.QRect(170, 90, 371, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.user_lineEdit.setFont(font)
        self.user_lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.user_lineEdit.setObjectName("user_lineEdit")
        self.pass_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.pass_lineEdit.setGeometry(QtCore.QRect(170, 150, 371, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.pass_lineEdit.setFont(font)
        self.pass_lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.pass_lineEdit.setObjectName("pass_lineEdit")
        self.pass_label = QtWidgets.QLabel(self.centralwidget)
        self.pass_label.setGeometry(QtCore.QRect(40, 146, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.pass_label.setFont(font)
        self.pass_label.setObjectName("pass_label")
        self.title_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.title_lineEdit.setGeometry(QtCore.QRect(170, 360, 461, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.title_lineEdit.setFont(font)
        self.title_lineEdit.setText("")
        self.title_lineEdit.setObjectName("title_lineEdit")
        self.title_label = QtWidgets.QLabel(self.centralwidget)
        self.title_label.setGeometry(QtCore.QRect(40, 356, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.title_label.setFont(font)
        self.title_label.setObjectName("title_label")
        self.addtxt_pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.addtxt_pushButton.setGeometry(QtCore.QRect(580, 480, 51, 41))
        self.addtxt_pushButton.setObjectName("addtxt_pushButton")
        self.addtxt_label = QtWidgets.QLabel(self.centralwidget)
        self.addtxt_label.setGeometry(QtCore.QRect(40, 476, 121, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.addtxt_label.setFont(font)
        self.addtxt_label.setObjectName("addtxt_label")
        self.addtxt_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.addtxt_lineEdit.setEnabled(True)
        self.addtxt_lineEdit.setGeometry(QtCore.QRect(170, 480, 411, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.addtxt_lineEdit.setFont(font)
        self.addtxt_lineEdit.setObjectName("addtxt_lineEdit")
        self.send_groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.send_groupBox.setGeometry(QtCore.QRect(20, 326, 631, 211))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.send_groupBox.setFont(font)
        self.send_groupBox.setObjectName("send_groupBox")
        self.main_lineEdit = QtWidgets.QLineEdit(self.send_groupBox)
        self.main_lineEdit.setGeometry(QtCore.QRect(150, 90, 461, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.main_lineEdit.setFont(font)
        self.main_lineEdit.setText("")
        self.main_lineEdit.setObjectName("main_lineEdit")
        self.main_label = QtWidgets.QLabel(self.send_groupBox)
        self.main_label.setGeometry(QtCore.QRect(20, 86, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.main_label.setFont(font)
        self.main_label.setObjectName("main_label")
        self.set_groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.set_groupBox.setGeometry(QtCore.QRect(20, 66, 551, 251))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.set_groupBox.setFont(font)
        self.set_groupBox.setObjectName("set_groupBox")
        self.span_label = QtWidgets.QLabel(self.set_groupBox)
        self.span_label.setGeometry(QtCore.QRect(20, 136, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.span_label.setFont(font)
        self.span_label.setObjectName("span_label")
        self.span_lineEdit = QtWidgets.QLineEdit(self.set_groupBox)
        self.span_lineEdit.setGeometry(QtCore.QRect(150, 140, 321, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.span_lineEdit.setFont(font)
        self.span_lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.span_lineEdit.setObjectName("span_lineEdit")
        self.oddtxt_label = QtWidgets.QLabel(self.set_groupBox)
        self.oddtxt_label.setGeometry(QtCore.QRect(20, 200, 271, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.oddtxt_label.setFont(font)
        self.oddtxt_label.setObjectName("oddtxt_label")
        self.oddtxt_lineEdit = QtWidgets.QLineEdit(self.set_groupBox)
        self.oddtxt_lineEdit.setEnabled(True)
        self.oddtxt_lineEdit.setGeometry(QtCore.QRect(230, 200, 241, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.oddtxt_lineEdit.setFont(font)
        self.oddtxt_lineEdit.setObjectName("oddtxt_lineEdit")
        self.oddtxt_pushButton = QtWidgets.QPushButton(self.set_groupBox)
        self.oddtxt_pushButton.setGeometry(QtCore.QRect(470, 200, 51, 41))
        self.oddtxt_pushButton.setObjectName("oddtxt_pushButton")
        self.span_unit_label = QtWidgets.QLabel(self.set_groupBox)
        self.span_unit_label.setGeometry(QtCore.QRect(480, 136, 41, 51))
        self.span_unit_label.setObjectName("span_unit_label")
        self.labtitle_label = QtWidgets.QLabel(self.centralwidget)
        self.labtitle_label.setGeometry(QtCore.QRect(260, 20, 261, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.labtitle_label.setFont(font)
        self.labtitle_label.setFrameShape(QtWidgets.QFrame.Box)
        self.labtitle_label.setAlignment(QtCore.Qt.AlignCenter)
        self.labtitle_label.setObjectName("labtitle_label")
        self.sendp_label = QtWidgets.QLabel(self.centralwidget)
        self.sendp_label.setGeometry(QtCore.QRect(20, 540, 131, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.sendp_label.setFont(font)
        self.sendp_label.setObjectName("sendp_label")
        self.send_progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.send_progressBar.setGeometry(QtCore.QRect(140, 550, 661, 31))
        self.send_progressBar.setProperty("value", 0)
        self.send_progressBar.setObjectName("send_progressBar")
        self.information_groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.information_groupBox.setGeometry(QtCore.QRect(580, 66, 221, 251))
        self.information_groupBox.setObjectName("information_groupBox")
        self.send_textBrowser = QtWidgets.QTextBrowser(self.information_groupBox)
        self.send_textBrowser.setGeometry(QtCore.QRect(10, 29, 201, 211))
        self.send_textBrowser.setObjectName("send_textBrowser")
        self.send_pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.send_pushButton.setGeometry(QtCore.QRect(660, 360, 141, 161))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.send_pushButton.setFont(font)
        self.send_pushButton.setObjectName("send_pushButton")
        self.set_groupBox.raise_()
        self.send_groupBox.raise_()
        self.user_label.raise_()
        self.user_lineEdit.raise_()
        self.pass_lineEdit.raise_()
        self.pass_label.raise_()
        self.title_lineEdit.raise_()
        self.title_label.raise_()
        self.addtxt_pushButton.raise_()
        self.addtxt_label.raise_()
        self.addtxt_lineEdit.raise_()
        self.labtitle_label.raise_()
        self.sendp_label.raise_()
        self.send_progressBar.raise_()
        self.information_groupBox.raise_()
        self.send_pushButton.raise_()
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 819, 30))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "邮件批量发送软件"))
        self.user_label.setText(_translate("MainWindow", "用户名:"))
        self.pass_label.setText(_translate("MainWindow", "授权码:"))
        self.title_label.setText(_translate("MainWindow", "主题:"))
        self.addtxt_pushButton.setText(_translate("MainWindow", "..."))
        self.addtxt_label.setText(_translate("MainWindow", "附件:"))
        self.send_groupBox.setTitle(_translate("MainWindow", "内容设置"))
        self.main_label.setText(_translate("MainWindow", "正文:"))
        self.set_groupBox.setTitle(_translate("MainWindow", "发送设置"))
        self.span_label.setText(_translate("MainWindow", "发送间隔:"))
        self.span_lineEdit.setText(_translate("MainWindow", "1"))
        self.oddtxt_label.setText(_translate("MainWindow", "目标地址邮箱文件:"))
        self.oddtxt_pushButton.setText(_translate("MainWindow", "..."))
        self.span_unit_label.setText(_translate("MainWindow", "秒"))
        self.labtitle_label.setText(_translate("MainWindow", "邮件批量发送软件"))
        self.sendp_label.setText(_translate("MainWindow", "发送进度:"))
        self.information_groupBox.setTitle(_translate("MainWindow", "提示窗"))
        self.send_pushButton.setText(_translate("MainWindow", "发送"))

功能代码

import sys,os,time
from PyQt5.QtCore import QThread,pyqtSignal
from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog
import smtplib  # smtp协议封装库;email用来创建邮件
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import windows_screen


# QT多线程:界面相应的功能函数
class mailsend_thread(QThread):
    # 创建槽变量
    send_a_data = pyqtSignal(int)       # 弹出发送进度条数据
    txt_a_data = pyqtSignal(str)        # 弹出发送进度数据

    def __init__(self, parent=None):
        super(mailsend_thread, self).__init__(parent)
        #设置工作状态与初始num数值
        self.send_progressBar_data = 0
        self.send_a_data.emit(self.send_progressBar_data)

    # 发送邮件函数
    def run(self):
        i_sum = 0                        # 发送邮件序号
        for i in receiver_list:
            self.send_functtion(i)       # 调用发送函数:传入发送邮箱地址
            i_sum += 1
            self.send_progressBar_data = int((i_sum / len(receiver_list))*100)      # 统计发送进度
            self.str_data = str(i_sum)                                              # 字符化发送序号
            self.txt_a_data.emit(self.str_data)                                     # 弹出发送进度条数据
            self.send_a_data.emit(self.send_progressBar_data)                       # 弹出发送进度

            time.sleep(mail_span_time)      # 发送延时

        self.send_a_data.emit(100)          # 发送完成后填满进度条


  # 发送函数
  # mail_user为邮箱用户名,mail_pass为授权码,receivers为接收邮箱地址(列表格式)
  # mail_subject为邮箱主题,mail_text为正文内容,mail_txt_add为附件地址


    def send_functtion(self, receivers):

        msg = MIMEMultipart()  # 创建一个带附件的实例
        msg["Subject"] = mail_subject
        msg["From"] = mail_user
        msg["To"] = ','.join([receivers])

        # ---文字部分---
        part = MIMEText(mail_text)
        msg.attach(part)

        # ---附件部分---
        part = MIMEApplication(open(mail_txt_add, 'rb').read())
        part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(mail_txt_add))
        msg.attach(part)

        try:
            s = smtplib.SMTP(mail_smtp, timeout=(mail_span_time*len(receiver_list)+1000))  # 连接smtp邮件服务器,端口默认是25;超时时间设置大一点
            s.login(mail_user, mail_pass)  # 登陆服务器
            s.sendmail(mail_user, receivers, msg.as_string())  # 发送邮件
            s.close()
        except Exception as e:
            print("error:", e)



# 软件主界面
class a0_MyMainForm(QMainWindow,windows_screen.Ui_MainWindow):
    def __init__(self,parent=None):
        super(a0_MyMainForm,self).__init__(parent)
        #加载页面
        self.setupUi(self)
        self.initUI()
        # 禁止窗口放大
        self.setFixedSize(self.width(), self.height())

    #链接函数
    def initUI(self):
        # 1.选择发送邮件地址文件
        self.oddtxt_pushButton.clicked.connect(self.oddtxt_function)
        # 2.选择附件
        self.addtxt_pushButton.clicked.connect(self.addtxt_function)
        # 3.发送
        self.send_pushButton.clicked.connect(self.send_function)

    # 1.选择发送邮件地址文件
    def oddtxt_function(self):
        send_directory = QFileDialog.getOpenFileName(self, "选取文件", "./", "All Files (*);;Text Files (*.txt)")
        if send_directory:
            # 如果选择了路径
            # 取返回第一个字符串(返回值:第一个为地址,第二个为类型)
            send_address = send_directory[0]
        else:
            # 未选择路径
            send_address = ''
        # 显示选取的地址
        self.oddtxt_lineEdit.setText(send_address)

    # 2.选择附件
    def addtxt_function(self):
        send_directory = QFileDialog.getOpenFileName(self, "选取文件", "./", "All Files (*);;Text Files (*.txt)")
        if send_directory:
            # 如果选择了路径
            send_address = send_directory[0]
        else:
            # 未选择路径
            send_address = ''
        # 显示选取的地址
        self.addtxt_lineEdit.setText(send_address)

    # 3.获取发送参数
    def send_function(self):
        # 声明为全局变量,直接调取,具体变量解释见下
        global mail_user, mail_smtp, mail_pass, receiver_list
        global mail_subject, mail_text, mail_txt_add,mail_span_time

        # 3.1 mail_user为邮箱用户名
        mail_user = self.user_lineEdit.text()
        # 3.2 mail_smtp 为邮箱服务器类型
        mail_sort = mail_user.split('@')[1]     # 截取邮箱后缀
        mail_smtp = "smtp."+mail_sort           # 生成邮箱服务器类型
        # 3.3 mail_pass为授权码
        mail_pass = self.pass_lineEdit.text()
        # 3.4 receivers为接收邮箱地址(列表格式)
        receiver_txt_add = self.oddtxt_lineEdit.text()  # 读取接收邮箱文件地址
        file = open(receiver_txt_add)                   # 打开文件
        rec_txt = file.read()                           # 读取文件内容
        file.close()                                    # 读取完成后关闭文件
        receiver_list = []                              # 创建接收邮箱地址存放列表
        for i in rec_txt.split(','):                    # 写入接收邮箱地址
            receiver_list.append(i)
        # 3.5 mail_subject为邮箱主题
        mail_subject = self.title_lineEdit.text()
        # 3.6 mail_text为正文内容
        mail_text = self.main_lineEdit.text()
        # 3.7 mail_txt_add为附件地址
        mail_txt_add = self.addtxt_lineEdit.text()
        # 3.8 mail_span_time为发送间隔时间
        try:
            mail_span_time = float(self.span_lineEdit.text())
        except:
            mail_span_time = 0

        # 3.9 开始发送邮件
        self.send_progressBar.setValue(0)                           # 初始化发送进度条
        self.send_textBrowser.append('开始发送邮件……')                # 显示发送提示
        # 实例化多线程对象
        self.thread = mailsend_thread()                             # 创建发送线程
        self.thread.send_a_data.connect(self.progress_display)      # 弹出发送进度条
        self.thread.txt_a_data.connect(self.txt_display)            # 弹出发送提示
        self.thread.start()                                         # 开始线程

    # 3.9.1 更新发送进度条
    def progress_display(self,num):
        self.send_progressBar.setValue(num)
    # 3.9.2 更新发送进度提示
    def txt_display(self,txt):
        if int(txt) == len(receiver_list):
            self.send_textBrowser.append('\n第' + txt + '个邮件发送完成,')
            self.send_textBrowser.append('\n全部邮件发送完成!')
        else:
            self.send_textBrowser.append('\n第' + txt + '个邮件发送完成,')





# 程序运行函数
def mw_run():
    app = QApplication(sys.argv)
    myWin = a0_MyMainForm()
    myWin.show()
    sys.exit(app.exec_())

if __name__== '__main__':
    mw_run()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值