导入包
import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 构建邮件头信息,包括发件人,接收人,标题等
import datetime
from pymysql import *
# from pyhive import hive
# from impala.dbapi import connect
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.rcParams[u'font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
from datetime import datetime,timedelta
邮件部分
def send_email(title, message, receivers):
# 设置服务器所需信息
# 163邮箱服务器地址
# 设置服务器所需信息
# 163邮箱服务器地址
mail_host = 'XX.163.com'
# 163邮箱端口号
port = 465
# 163用户名
mail_user = '[email protected]'
# 密码(部分邮箱为授权码)
mail_pass = 'AABBCC'
# 邮件发送方邮箱地址
sender = '[email protected]'
# 邮件主题:拼接当日的时间
current_day = datetime.now().strftime('%Y%m%d')
message['Subject'] = '每日简表_%s'%current_day
# 发送方信息
message['From'] = 'reporter<%s>'%sender
# 接受方信息
reces = ''
for i in range(len(receivers)):
reces = reces+',receiveer%d<%s>'%(i+1,receivers[i])
message['To'] = reces
# 开始发送邮件
try:
# 25端口,非ssl协议
# smtpObj = smtplib.SMTP()
# windows 可行
# smtpObj = smtplib.SMTP_SSL()
# linux 才可行
smtpObj = smtplib.SMTP_SSL(host=mail_host)
# 连接到服务器
smtpObj.connect(mail_host, port)
# 登录到服务器
smtpObj.login(mail_user, mail_pass)
# 发送
smtpObj.sendmail(sender, receivers, message.as_string())
# 退出
smtpObj.quit()
print('success')
except smtplib.SMTPException as e:
print("发送邮件错误:")
print('error', e)
python从mySQL提取
cursor.description
方法会将每个字段的字段名,字段类型,字段长度...等等字段的属性列出来.
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-description.html
def executesql_mysql(sql):
# 连接 mysql 数据库
conn = connect(host='106.15.121.232',
port=3306,
database='datafrog05_adventure',
user='frogdata05',
password='Frogdata!123')
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
# 返回的是list(tuple) 没有表头
# 保存字段名字 为DF添加表头
columns = []
for i in range(len(cursor.description)):
columns_name = cursor.description[i][0].split('.')[-1]
columns.append(columns_name)
table = pd.DataFrame(list(results))
table.columns = columns
cursor.close()
conn.close()
return table
python处理数据&画图
def get_message(test_to_html):
# 转换时间日期为标准格式
test_to_html['create_date'] = test_to_html['create_date'].map(lambda x:
datetime.strptime(x,'%Y-%m-%d'))
# 当日数据
today_info = test_to_html[test_to_html['is_today'] == 1]
today_info_sum = today_info[['sum_amount', 'sum_order']].sum()
#本月数据
tomonth_info = test_to_html[test_to_html['is_current_month'] == 1]
tomonth_info_sum = tomonth_info[['sum_amount', 'sum_order']].sum()
#本季数据
toquarter_info = test_to_html[
test_to_html['is_current_quarter'] == 1]
toquarter_info_sum = toquarter_info[['sum_amount', 'sum_order']].sum()
#本年数据
toyear_info = test_to_html[test_to_html['is_current_year'] == 1]
toyear_info_sum = toyear_info[['sum_amount', 'sum_order']].sum()
table_today = pd.DataFrame({'指标': ['销售额', '订单量'],
'今日': today_info_sum,
'当季': toquarter_info_sum,
'当月': tomonth_info_sum,
'当年': toyear_info_sum}
).reset_index(drop=True)
# picture_time = datetime.now().date() - timedelta(days=15)
picture_time = (datetime.now().date() -
timedelta(days=45)).strftime('%Y-%m-%d')
picture_table = test_to_html[test_to_html['create_date'] >=
picture_time]
picture_table = picture_table.groupby('create_date').sum()
[['sum_amount',
'sum_order','sum_amount_goal','sum_order_goal']]
# plt.show()
# 绘制图形
x = picture_table.index
y1 = picture_table['sum_amount']
y2 = picture_table['sum_order']
y3 = picture_table['sum_amount']/picture_table['sum_amount_goal']
y4 = picture_table['sum_order']/picture_table['sum_order_goal']
fig = plt.figure(figsize=(14, 20))
# 划分子图
ax1 = fig.add_subplot(411) # 等价于fig.add_subplot(4,1,1)
ax2 = fig.add_subplot(412)
ax3 = fig.add_subplot(413)
ax4 = fig.add_subplot(414)
# 开始画图,可以使用 ax1、ax2设置相应的参数
ax1.plot(x, y1, 'g', label='first')
ax1.set_xlabel('时间', fontsize=15)
ax1.set_ylabel('销售额', fontsize=15)
ax1.set_title('过去45天销售趋势', fontsize=25, loc='left')
ax2.plot(x, y2, 'r', label='second')
ax2.set_xlabel('时间', fontsize=15)
ax2.set_ylabel('订单量', fontsize=15)
# 开始画图,可以使用 ax1、ax2设置相应的参数
ax3.plot(x, y3, 'b', label='first')
ax3.set_xlabel('时间', fontsize=15)
ax3.set_ylabel('销售目标达成', fontsize=15)
ax3.axhline(y=1, lw=2, ls="--", color="g") #添加参考线
ax4.plot(x, y4, 'r', label='second')
ax4.set_xlabel('时间', fontsize=15)
ax4.set_ylabel('订单量目标达成', fontsize=15)
ax4.axhline(y=1, lw=2, ls="--", color="g")
plt.xticks(rotation=30)
# x坐标增加15°倾斜
for tick in ax1.get_xticklabels():
tick.set_rotation(15)
for tick in ax2.get_xticklabels():
tick.set_rotation(15)
for tick in ax3.get_xticklabels():
tick.set_rotation(15)
for tick in ax4.get_xticklabels():
tick.set_rotation(15)
img_file = "examples.png"
plt.savefig(img_file)
得到html格式的表格
https://blog.csdn.net/u012111465/article/details/82713561
# 样式添加
# 添加表内容
df_html = table_today.to_html(escape=False, index=False)
head = \
"""
'''设置文档标题和其它在网页中不显示的信息'''
//这里是元信息。里面可以定义网
页的字符格道式和写出网页的详细信息(如。作者。关键词等)
"""
# head和body是固定格式
# 构造模板的附件(100)
body = \
"""
Adventure Works Cycles 简报
战绩
{df_html}
—— 本次报告完 ——
""".format(df_html=df_html)
# body中有content的format格式
# content = "" + head + body + ""
content = head + body
html_file = open('t4.html', 'w', encoding='UTF-8', newline='')
html_file.write(content)
html_file.close()
return content,img_file
运行本py文件时 执行以下内容
if __name__ == '__main__':
sql = "SELECT * FROM dw_order_by_day_mdx "
# sql = "show databases"
# test_to_html = executesql_hive(sql)
test_to_html = executesql_mysql(sql)
print(test_to_html)
# 获取要发送的 html 和 图片 信息
content_html,img_file = get_message(test_to_html)
# 目标:设置email要发送的内容,也可以直接就是 MIMEText 的内容,
# 但是下面这样可以追加文本、html、图片等信息
message = MIMEMultipart()
# message = MIMEMultipart('alternative')
# 1、添加文本内容
# content_text = '邮件发送测试中..'
# message.attach(MIMEText(content_text,'plain','utf-8'))
# 2、添加 html 格式的内容
message.attach(MIMEText(content_html,'html','utf-8'))
# 3、添加图片信息
with open(img_file,'rb') as f:
img_info = f.read()
img = MIMEImage(img_info)
img.add_header('Content-ID', 'io')
# body部分有io文件
message.attach(img)
# 最后:设置收件箱地址,可以发邮件了
receivers = ['[email protected]','obvrou.163.com']
# 发送邮件
send_email('每日简报',message,receivers)
- 添加图片的实现原理:
将本地图片加入到邮件附件中:
m_img.add_header('Content-ID', '
用来设置图片id')
然后通过邮件html文本引入图片:
参见:https://blog.csdn.net/qq_38161040/article/details/90140231
添加附件等其他操作 参见:https://blog.csdn.net/qq_33472765/article/details/81022471
扩展标题add_header:
https://www.cnblogs.com/zhangxinqi/p/9113859.html
一次性多张图片发送:
https://www.jb51.net/article/167391.htm