python定时邮件发送_正文添加图片_添加附件_循环发送多人

实现功能:

  • 从数据库中获取前一天订单数据,分区域生成汇总文件(.csv)和明细文件(.csv)保存,将文件保存到指定目录下
  • 生成汇总文件内容截图,绘制产品分布饼图截图,保存两个截图,将文件保存到指定目录下
  • 通过邮件将每日各区域所需的两个文件及两个截图在每日早上8点准时发送及抄送各区域指定人员

导入数据所需的包~


#邮件发送模块-----------
import smtplib  # 加载smtplib模块
from email.mime.text import MIMEText
from email.utils import formataddr
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
#数据连接清洗模块
import psycopg2
import pandas as pd
import datetime
import os
import matplotlib.pyplot as plt
#表格内容优化
from openpyxl  import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.styles import Font, colors, Alignment,Border,Side,PatternFill
#截图
import pythoncom
from PIL import ImageGrab, Image
from win32com.client import Dispatch, DispatchEx
import uuid

执行脚本


#数据库连接及数据清洗--------------------------------------------------------------------------
def  get_data(database_config,sql,k):
    conn = psycopg2.connect(database=database_config["database"],
                            user=database_config["user"],
                            password=database_config["password"], 
                            host=database_config["host"],
                            port=database_config["port"])
    cursor = conn.cursor()
    cursor.execute(sql)
    df = pd.DataFrame(cursor.fetchall())    #获取订单明细数据
    lst = list()
    for a in cursor.description:
        lst.append(a[0]) 
    df.columns = lst
    df = df[df['region']==k]
    cursor.close()   

    #数据清洗
    df_sum = df.groupby('package_name').agg({'uid':'nunique','id':'count'})   #获取订单汇总数据
    df_sum['percent'] = df_sum['uid']/df_sum['uid'].sum()   #计算没类商品订单购买用户数占比
    df_sum['new_package'] = list(df_sum.index)
    df_sum.loc[df_sum['percent']<0.02,'new_package'] = '其他'   #将占比小于2%的类型归类为其他
    return df,df_sum

#文件内容保存----------------------------------------------------------------------------------    
def get_document_file(file_path,df,df_sum,k):
    new_dir = file_path+'\\'+str(datetime.date.today())+'\\'+ k
    #创建当日文件保留目录
    if not os.path.isdir(file_path+'\\'+str(datetime.date.today())):
        os.mkdir(os.path.join(file_path,str(datetime.date.today())))
    if not os.path.isdir(new_dir):
        os.mkdir(os.path.join(file_path,str(datetime.date.today()),k))

    #明细数据保留csv文件-------------------------------------------    
    df.to_csv(new_dir +'\\'+str(datetime.date.today())+'_'+ k +'_订单明细文件.csv',encoding='utf_8_sig')
    print(new_dir+'\\'+str(datetime.date.today())+ k +'订单明细文件保存成功')

    #汇总数据保留csv文件--------------------------------------------
    #df_sum.to_csv(new_dir+'\\'+str(datetime.date.today())+'_订单汇总文件.csv',encoding='utf_8_sig')
    font_title = Font(size=12, bold=True, name='微软雅黑',  color="000000")
    fill = PatternFill(patternType="solid", start_color="5B9BD5")#纯色填充
    border = Border(left=Side(border_style='thin',color='000000'),
    right=Side(border_style='thin',color='000000'),
    top=Side(border_style='thin',color='000000'),
    bottom=Side(border_style='thin',color='000000'))

    wb = Workbook()
    ws = wb.active

    for r in dataframe_to_rows(df_sum.iloc[:,:2], index=True, header=True):  #数据写入ws
        ws.append(r)
    for row in ws:   #标题行格式设置
        for cell in row:
            cell.border  = border
            if cell.row == 1:
                cell.font  = font_title   #如果是第一行的,设置大字体
                cell.fill  = fill         #第一行设置背景填充颜色 
    ws.column_dimensions['A'].width = max(map(lambda x:len(x),list(df_sum.index)))*1.7+1
    wb.save(new_dir+'\\'+str(datetime.date.today())+'_'+ k +"_订单汇总文件.xlsx")
    print(new_dir+'\\'+str(datetime.date.today())+ k +'订单汇总文件保存成功')
    return new_dir

#对汇总文件内容进行截图-----------------------------------------    
def get_document_img(new_dir,df_sum,k):
    screen_area = 'A1:C'+str(df_sum.shape[0]+2)
    excel = DispatchEx("Excel.Application")  # 启动excel
    wb = excel.Workbooks.Open(new_dir+'\\'+str(datetime.date.today())+'_'+ k +"_订单汇总文件.xlsx")  # 打开excel
    ws = wb.Sheets('sheet')  # 选择sheet
    ws.Range(screen_area).CopyPicture()  # 复制图片区域
    ws.Paste()
    name = str(uuid.uuid4())  # 重命名唯一值
    new_shape_name = name[:6]
    excel.Selection.ShapeRange.Name = new_shape_name    # 将刚刚选择的Shape重命名,避免与已有图片混淆

    ws.Shapes(new_shape_name).Copy()  # 选择图片
    img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
    img.save(new_dir+'\\'+str(datetime.date.today())+'_'+ k+"_汇总数据截图.png")  # 保存图片
    img_path_doc = new_dir+'\\'+str(datetime.date.today())+'_'+ k+"_汇总数据截图.png"
    wb.Close(SaveChanges=0)  # 关闭工作薄,不保存
    excel.Quit()  # 退出excel
    return img_path_doc
    print('汇总数据截图完成!')
    
#汇总图表保留图片文件-------------------------------------------
def get_data_img(new_dir,df_sum,k):
    df_pie = df_sum.groupby('new_package')['uid'].sum().sort_values(ascending = False)
    plt.figure(figsize=(8,8))
    plt.pie(x=df_pie, #绘制数据
            labels=df_pie.index,#添加编程语言标签
            autopct='%.1f%%',#设置百分比的格式,保留3位小数
            pctdistance=0.8, #设置百分比标签和圆心的距离
            labeldistance=1.0,#设置标签和圆心的距离
            startangle=180,#设置饼图的初始角度
            counterclock= False,#是否为逆时针方向,False表示顺时针方向
            wedgeprops= {'linewidth':1,'edgecolor':'white'},#设置饼图内外边界的属性值
            textprops= {'fontsize':12,'color':'black'},#设置文本标签的属性值
           ) 

    plt.title(k+'昨日订单用户数分布',fontsize=17)
    plt.savefig(new_dir+'\\'+str(datetime.date.today())+'_'+ k+"_订单用户分布图.png",
                dpi=200,
                bbox_inches='tight') 
    img_path_df = new_dir+'\\'+str(datetime.date.today())+'_'+ k+"_订单用户分布图.png"
    return img_path_df

def send_email(new_dir,email_config,img_path,k,v):
    try:
        msg = MIMEMultipart('related')
        msg['From'] = formataddr(["数据分析",email_config['sender']])  # 发件人邮箱昵称、发件人邮箱账号
        msg['To'] = formataddr(["receiver",v['receive']])  # 收件人邮箱昵称、收件人邮箱账号
        msg['Cc'] = ','.join(v['cc_mail'])
        msg['Subject'] = k + email_config['sub'] 
        print('读取账号信息完成')
        #文本信息
        #txt = MIMEText('this is a test mail', 'plain', 'utf-8')
        #msg.attach(txt)

        #正文内容
        body =  """
            <b>昨日订单概括:</b><br></br>
            <!doctype html> <html><head> <meta charset="utf-8"></head>
            <body><div>
            <p>各位运营同事大家好,以下是昨日订单数据情况,包括订单汇总文件,订单明细文件。套餐类型分布饼图,汇总文件截图。:</P>
            </div> <style type="text/css">p{text-indent: 2em; /*首行字符缩进设置*/}</style>
            <p><b>订单分布饼图:</b></p>
            <p><img src="cid:image1"></p>
            <p><b>汇总文件内容截图:</b></p>
            <p><img src="cid:image2"></p>
            <span style="float:right;">总冠军:Jordan</span>
            </body>
            </html>
            """
        text = MIMEText(body, 'html')  #, 'utf-8'
        msg.attach(text)
        
        msgImage = MIMEImage(open(img_path[0], 'rb').read())
        # 定义图片 ID,在 HTML 文本中引用
        msgImage.add_header('Content-ID', '<image1>')
        msg.attach(msgImage)
        
        msgImage = MIMEImage(open(img_path[1], 'rb').read())
        # 定义图片 ID,在 HTML 文本中引用
        msgImage.add_header('Content-ID', '<image2>')
        msg.attach(msgImage)
        print('正文信息构建完成')

 #附件信息添加------------------------------------------------------------------------       
        #汇总附件信息 ①
        path = new_dir+'\\'+str(datetime.date.today())+'_'+ k +"_订单汇总文件.xlsx"
        file_name = str(datetime.date.today())+'_'+ k+"_订单汇总文件.xlsx"
        attach = MIMEApplication(open(path,'rb').read(),encoding="utf8")
        attach.add_header('Content-Disposition', 'attachment', filename=('gbk', '', file_name))
        msg.attach(attach)
        print('订单汇总文件附件添加成功')

        #明细附件信息 ②
        path = new_dir+'\\'+str(datetime.date.today())+'_'+ k +"_订单明细文件.csv"
        file_name = str(datetime.date.today())+'_'+ k+"_订单明细文件.csv"
        attach = MIMEApplication(open(path,'rb').read(),encoding="utf8")
        attach.add_header('Content-Disposition', 'attachment', filename=('gbk', '', file_name))
        msg.attach(attach)   
        print('订单明细文件附件添加成功')    

        #发送邮件
        server = smtplib.SMTP(email_config['mailserver'], email_config['port'])  # 发件人邮箱中的SMTP服务器,端口是25
        server.login(email_config['sender'], email_config['passwd'])  # 发件人邮箱账号、邮箱密码
        server.sendmail(email_config['sender'], 
                        [v['receive']]+v['cc_mail'], 
                        msg.as_string())  # 发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()
        print('邮件发送成功\n')
    except Exception as e:
        print(e)


if __name__ == '__main__':
    #设置基本文件参数-----------------------------------------------
    file_path = r'C:\Users\Jordan\Desktop\邮件_每日外发3'    #设置根目录
    database_config = {
    "database":"database",
    "user":"admin",
    "password":"admin", 
    "host":"localhost",
    "port":"443"}
    sql = 'select * from t_order where create_time = current_date-1'
    
    email_config = {
    'sender' : 'Jordan.Li@baidu.com',  # 发件人邮箱账号
    'passwd' : 'Jordan123',
    'mailserver' : 'smtp.baidu.com',
    'port': '25',
    'sub' : '昨日订单概括数据'}
    receiver_list = {
        '华南':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']},
        '华北':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']},
        '西北':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']},
        '西南':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']},
        '华东':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']},
        '华中':{'receive':'James.king@baidu.com',
              'cc_mail':['kobe.liu@baidu.com','harden.lin@baidu.com']}
    }
    
    #执行主体内容-------------------------------------------------

    for k,v in receiver_list.items():
        print('传入首个参数:',k)
        df,df_sum = get_data(database_config,sql,k)     #获取明细数据,汇总数据
        new_dir = get_document_file(file_path,df,df_sum,k)   #保存明细数据,汇总数据为excel文件
        img_path_doc = get_document_img(new_dir,df_sum,k)                   #保存汇总文件截图数据
        img_path_df = get_data_img(new_dir,df_sum,k)                       #保存汇总数据饼图
        img_path = [img_path_doc,img_path_df]     #截图文件路径
        send_email(new_dir,email_config,img_path,k,v)

执行结果如下:

指定目录下每天生成6个文件夹,每个文件夹内包含对应区域4个文件。

自动发送6份邮件,每个邮件发送对应的人,邮件正文包含截图,文件附于附件中。

 

定时任务发送

在 计算器右击 --> 选择管理 -->任务计划程序:

前面一步步按向导走就行,除了设置时间,就是启动程序这里有需要注意的地方。设置好执行脚本和程序,就能每天通过window自动调用这个脚本了。

设置启动程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值