本帖最后由 cick 于 2023-9-21 11:51 编辑
实现功能
通过本地navicat链接远程服务器mysql 查询视图中对应表格不同维度数据发送给指定多个领导邮箱定时接收报表。代码比较短。
说明下 在下面代码中我用的方式是用任务计划每天8点指定这个xx.py缺点电脑要一直开着。希望路过的大佬可以帮忙改造下成为界面化的,到时候可以打包exe 用json存储下对应数据库配置信息,邮箱发送配置信息。我是真菜,是真不会,尝试改了下踩了python 坑一会附图见下方。
效果图见附件下图。改写的没成功,在学习中,改成json 存数据库、发送邮件配置信息不会。求大佬改造成界面化。
菜鸟第一篇,注册好多年了,一直潜水摸鱼,发个工作中用到的提供给大家,有py大神能改下界面化就更好。 反正自己也不会py只能网上搬来搬去。
import time
import urllib
import schedule
import sqlalchemy
import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
#因为在配置数据库的时候有特殊字符,因此需要屏蔽下特殊字符如空格@、#等,因为用的py3.8.10所以这里需要改成urllib.parse.quote("pwd")
encoded_password = urllib.parse.quote("52pj365@qq.com")
# 配置数据库连接
db_config = {
'host': '127.0.0.1', # 本地配置了navicat的当前数据库连接了,直接配置你的链接地址,如果是远程服务器地址直接输入服务器IP;
'port': 3306, # 这里是mysql端口号就按照你实际的填写。
'user': 'root', # 链接数据库用户
'password': encoded_password, # 主要是有特殊字符,所以就有了上面的urllib.parse.quote方式
'database': 'databasename' # 数据库名
}
# 配置邮箱信息
email_config = {
'smtp_server': 'smtp.qq.com', # 我这里使用qq邮箱发送,如果你是其他邮箱,自行登录到网页版邮箱配置下对应的授权码
'smtp_port': 465, # 通用端口
'sender_email': '123@qq.com',
'sender_password': 'iojqade123123wew', # 需要使用授权码,去各自的邮箱进行开通授权即可,根据你邮箱配置自己修改
'receiver_emails': ['1@163.com','2@qq.com'] # 这个地方也改过,之前是单个邮箱,因为要多个人同时接收,所以这里就用[]添加多个接收数据邮箱,重见用逗号分隔开。
}
def query_and_send_email():
try:
# 创建数据库连接
engine = sqlalchemy.create_engine(
f"mysql+pymysql://{db_config['user']}:{db_config['password']}@{db_config['host']}:{db_config['port']}/{db_config['database']}"
)
# 执行第一个查询,from表名根据你要查的自己替换可追加where查询,日常查询的都可以添加row行号追加需要注意你当前mysql版本,版本不同写法不同。表1:(多门店数据统计,VIP1\vip2\vip3数据各有多少人)
query_ak = "SELECT * FROM 表1"
df_ak = pd.read_sql(query_ak, engine)
# 执行第二个查询,表1:查询数据
query_bbc = "SELECT * FROM 表2"
df_bbc = pd.read_sql(query_bbc, engine)
# 执行第三个查询 表3:
query_bbd = "SELECT * FROM 表3"
df_bbd = pd.read_sql(query_bbd, engine)
# 获取当前日期,给标题追加个当前时间
current_date = datetime.now().strftime("%Y-%m-%d")
# 构建邮件内容,拼接下日期。
subject = f"数据库查询结果 - {current_date}"
message = MIMEMultipart()
message['Subject'] = subject
message['From'] = email_config['sender_email']
message['To'] = ', '.join(email_config['receiver_emails'])
# 将数据添加到邮件正文中 这里需要追加f才能显示当前查询日期,上面是查询了三个条件,所以就对应添加查询标题名字根据你实际进行调整下。如果需要其他格式请自行修改下。
html_content = f"<h1>数据查询结果 - 统计及汇总-{current_date}</h1>" + df_ak.to_html() + "<br><br>" \
+ f"<h1>数据查询结果 - 数据统计-{current_date}</h1>" + df_bbc.to_html()+ "<br><br>" +\
f"<h1>数据查询结果 - 注册统计(上月+上周+昨日+今日+7日+30日)-{current_date}</h1>" + df_bbd.to_html()
message.attach(MIMEText(html_content, 'html'))
# 发送邮件
with smtplib.SMTP_SSL(email_config['smtp_server'], email_config['smtp_port']) as server:
server.login(email_config['sender_email'], email_config['sender_password'])
server.sendmail(email_config['sender_email'], email_config['receiver_emails'], message.as_string())
print("邮件发送成功!")
except Exception as e:
print("发生错误:", e)
# 调用函数直接执行发送,如果需要改成定时的就把下面这行注释掉。把定时任务早上8点和循环定时任务的注释都取消就可以事项每天自动8点发送到指定多个邮箱。缺点是界面要一直开着。手动录入定时时间,自动触发查询
query_and_send_email()
# # # 设置定时任务,这里如果你要进行定时发送,可以注释query_and_send_email()这个,下面的注释取消即可。我的是改成直接任务计划添加了定时所以下面定时我就取消了。
# schedule.every().day.at("08:00").do(query_and_send_email) # 每天早上8点发送
#
# # 循环执行定时任务
# while True:
# schedule.run_pending()
# time.sleep(1)
|