Python 自动发送邮件

该博客展示了如何使用Python发送包含数据可视化图表和Excel数据分析的邮件。通过matplotlib和pandas库处理数据,创建图表,并将其插入到HTML邮件正文中。同时,邮件还附带了Excel文件和多个图片附件,实现了一站式的数据分析报告发送功能。
摘要由CSDN通过智能技术生成

Python 自动发送邮件:可以使用的代码如下

参考代码:

# -*- coding: utf-8 -*-
"""
HaoMiaoWuXian

"""

import os

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
import matplotlib as mpl

import smtplib
from email.message import EmailMessage
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

# --------------------------Part 0 set initial parameter-------------------------------------------------
mail_user = None            # 邮箱登录名
mail_pass = None            # 邮箱授权码,可百度如何获取
 
sender    = None            # 发件人
receivers = None            # 收件人列表,list形式
chaosong  = None            # 抄送人列表,list形式
# --------------------------------------------------------------------------------------------------------
infoStr = {"bodeText":None,
           "data_link":None,
           "ImageInfo":[],
           "AttachFiles":[],           #需要的全局变量
           "Table_Data":None}
msg = []

def Init_Private_Message():            #自己的私人信息,要在这里填写
    global mail_user
    global mail_pass
    global sender
    global receivers
    global chaosong
    
    mail_user = ''               # 邮箱登录名
    mail_pass = ''               # 邮箱授权码,可百度如何获取
 
    sender    = ''               # 发件人
    receivers = ['']             # 收件人列表,list形式
    chaosong  = ['']             # 抄送人列表,list形式
    
    mpl.rcParams['font.sans-serif'] = ['KaiTi']     # 设置要使用字体
    mpl.rcParams['font.serif'] = ['KaiTi']
    mpl.rcParams['axes.unicode_minus'] = False      # 使 - 号显示

    os.chdir(r'D:\code') # 设置文件路径

def Set_mail_Para(subject):
    # 设置邮件体对象
    global msg
    msg = MIMEMultipart()                         # 邮件体对象,此处可加入参数, 具体可百度
    #subject = 'python send email test'           # 邮件主题
    msg['subject'] = Header(subject, 'utf-8')     # 加入邮件主题
    msg['From'] = "{}".format(sender)             # 加入邮件发送人
    msg['To'] = ",".join(receivers)               # 加入邮件接收人
    msg['Cc'] = ",".join(chaosong)                # 加入邮件抄送人,如无,可注释掉

def Process_Excel_Data_Need():          #用户可以自己定义要处理的是什么
    df = pd.read_excel('零售总额.xlsx', sheet_name = 'Sheet1')
    df['年'] = df['统计时间'].apply(lambda x: x[:5])
    #print(df['年'])
    #print(len(df))
    # 图片
    df_x = np.arange(len(df)); df_real_x = df['统计时间']; df_y = df['社会消费品零售总额(亿元)']
    fig = plt.figure(figsize=(10,6))
    plt.plot(df_x, df_y ,  label="社会消费品零售总额(亿元)_label")
    xticks = np.arange(0,len(df_x)+1,12)#start,stop,step
    xlabels = [df_real_x[x] for x in xticks[:-1]]+list(df_real_x)[-1:]
    #print(xticks)
    #print(xlabels)
    plt.xticks(xticks, xlabels)
    plt.legend(loc = 'upper left')
    fig.autofmt_xdate()
    plt.savefig("data_image.jpg")
    # 表格
    df_count = df.groupby('年', as_index=False)['统计时间','社会消费品零售总额(亿元)'].agg({'统计时间':len, '社会消费品零售总额(亿元)':sum})
    df_count['统计时间'] = df_count['统计时间']
    df_count.rename(columns = {'统计时间':'统计总月份数', '社会消费品零售总额(亿元)':'每年零售总额(亿元)'}, inplace=True)
    return df_count
    
def Process_DataInfo_MaiNeed():         #用户可以自己定义要放置什么资源
    global infoStr
    bodyText = "This is a text mail by me!"
    infoStr["bodeText"] = bodyText
    data_link = 'https://blog.csdn.net/u012417290/article/details/77858531?spm=1001.2014.3001.5501'
    infoStr["data_link"]=data_link
    
    infoStr["ImageInfo"] = []
    imgSource1 = {"imageFile":"chart_1.png","chart_title":"chart_1_data:","imagewidth":720,"imageheight":600}
    imgSource2 = {"imageFile":"chart_2.png","chart_title":"chart_2_data:","imagewidth":720,"imageheight":600}
    imgSource3 = {"imageFile":"chart_3.png","chart_title":"chart_3_data:","imagewidth":720,"imageheight":600}
    imgSource4 = {"imageFile":"data_image.jpg","chart_title":"chart_4_data:","imagewidth":720,"imageheight":600}
    infoStr["ImageInfo"].append(imgSource1)
    infoStr["ImageInfo"].append(imgSource2)
    infoStr["ImageInfo"].append(imgSource3)
    infoStr["ImageInfo"].append(imgSource4)
    AttachFiles = ["chart_1.png","chart_2.png","chart_3.png",'零售总额.xlsx']
    infoStr["AttachFiles"]=AttachFiles

def Init_mail_text_Body(infoStr):
    HeadTmp = """\
<html>
  <head></head>
  <body>
    <pre style="font-family:arial">
    Dears,{bodeText}
    所用数据链接:<a href="{link}">Click</a>.
    </pre>""".format(bodeText = infoStr["bodeText"],link=infoStr["data_link"])
    
    imgTemp = ""
    imageHtml = ""
    imageNum = len(infoStr["ImageInfo"])
    for i in range(imageNum):
        imgTemp = """\
    <p>{chart_title}
    <br /><img src="cid:{imageIdx}", width={imagewidth}, height={imageheight}  >
    </p>
    """.format(imageIdx=str(i),chart_title=infoStr["ImageInfo"][i]["chart_title"],  imagewidth=infoStr["ImageInfo"][i]["imagewidth"],imageheight=infoStr["ImageInfo"][i]["imageheight"])
        imageHtml = imageHtml + imgTemp
    
    leftBody = """\
      </body>
</html>"""
    htmlFile = HeadTmp + imageHtml + leftBody
    htmlApart = MIMEText(htmlFile, 'html')
    
    for i in range(imageNum):
        imageFile = infoStr["ImageInfo"][i]["imageFile"]
        imageApart = MIMEImage(open(imageFile, 'rb').read(), imageFile.split('.')[-1])
        idexStr = '<'+str(i)+'>'
        imageApart.add_header('Content-ID', idexStr)
        msg.attach(imageApart)
    msg.attach(htmlApart)

def Mail_Add_AttachFile(infoStr):
    # 加入多个附件
    files = infoStr["AttachFiles"]
    for i in np.arange(len(files)):
        attFile = MIMEApplication(open(files[i], 'rb').read())
        attFile.add_header('Content-Disposition', 'attachment', filename=files[i])
        msg.attach(attFile)
        
def get_html_msg(df_s, table_title):
    """
    1. 构造html信息
    """
    df_html = df_s.to_html(escape=False)
 
    # 表格格式
    head = \
        """
        <head>
            <meta charset="utf-8">
            <STYLE TYPE="text/css" MEDIA=screen>
                table.dataframe {
                    border-collapse: collapse;
                    border: 2px solid #a19da2;
                    /*默认居中auto显示整个表格*/
                    margin: left;
                }
                table.dataframe thead {
                    border: 2px solid #91c6e1;
                    background: #f1f1f1;
                    padding: 10px 10px 10px 10px;
                    color: #333333;
                }
                table.dataframe tbody {
                    border: 2px solid #91c6e1;
                    padding: 10px 10px 10px 10px;
                }
                table.dataframe tr {
                }
                table.dataframe th {
                    vertical-align: top;
                    font-size: 14px;
                    padding: 10px 10px 10px 10px;
                    color: #105de3;
                    font-family: arial;
                    text-align: center;
                }
                table.dataframe td {
                    text-align: left;
                    padding: 10px 10px 10px 10px;
                }
                body {
                    font-family: 宋体;
                }
                h1 {
                    color: #5db446
                }
                div.header h2 {
                    color: #0002e3;
                    font-family: 黑体;
                }
                div.content h2 {
                    text-align: center;
                    font-size: 28px;
                    text-shadow: 2px 2px 1px #de4040;
                    color: #fff;
                    font-weight: bold;
                    background-color: #008eb7;
                    line-height: 1.5;
                    margin: 20px 0;
                    box-shadow: 10px 10px 5px #888888;
                    border-radius: 5px;
                }
                h3 {
                    font-size: 22px;
                    background-color: rgba(0, 2, 227, 0.71);
                    text-shadow: 2px 2px 1px #de4040;
                    color: rgba(239, 241, 234, 0.99);
                    line-height: 1.5;
                }
                h4 {
                    color: #e10092;
                    font-family: 楷体;
                    font-size: 20px;
                    text-align: center;
                }
                td img {
                    /*width: 60px;*/
                    max-width: 300px;
                    max-height: 300px;
                }
            </STYLE>
        </head>
        """
 
    # 构造正文表格
    body = \
        """
        <body>
        <div align="center" class="header">
            <!--标题部分的信息-->
            <!--<h1 align="left">{table_title}</h1>-->
            <p align="left">{table_title}</p>
        </div>
        <div class="content">
            {df_html}
        </div>
        </body>
        <br /><br />
        """.format(df_html=df_html, table_title=table_title)
 
    html_msg= "<html>" + head + body + "</html>"
#    这里是将HTML文件输出,作为测试的时候,查看格式用的,正式脚本中可以注释掉
#    fout = open('test.html', 'w', encoding='UTF-8', newline='')
#    fout.write(html_msg)
    return html_msg
 
def Mail_Constrct_Table(df_count, table_title):
   # html 内容
    html_msg = get_html_msg(df_count, table_title)
    content_html = MIMEText(html_msg, "html", "utf-8")
    msg.attach(content_html) 
        
def Sent_Mail():
    sftp_obj = smtplib.SMTP_SSL(host='smtp.163.com', port = 994)
    sftp_obj.login(mail_user, mail_pass)
    sftp_obj.sendmail(sender, receivers, msg.as_string())
    sftp_obj.quit()
    sftp_obj.close()
    print('\n'  + '__The email has been sent successfully')
    
Init_Private_Message()
Set_mail_Para("Mail_Subject__1")
df_count = Process_Excel_Data_Need()
Process_DataInfo_MaiNeed()
Init_mail_text_Body(infoStr)
Mail_Add_AttachFile(infoStr)
Mail_Constrct_Table(df_count,"table_example")
Sent_Mail()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值