当前位置:   article > 正文

python实战|表格拆分,邮件发送,回收表格合并统计_python excel 分组发送邮件

python excel 分组发送邮件

背景:运维每周会给到一份全国‘失联’快递柜的数据,作为分析人员。需要知道每台柜子的失联原因。

需要做的事:将这份快递柜的数据拆分成全国6个大区,对应的6个文件,在每个文件的最后新增一个字段,添加数据有效性,让运维同事选择原因,然后回收6份数据,将数据汇总合并,统计失联原因的分布。

第一步:数据拆分,将文件拆解成6份

初始数据结构,典型中国式报表,前两列数据合并,区域数据错误,需要调整替换,最后还需要增加一列包含数据验证的列,方便一线同事选择,也方便后续数据汇总。

  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. from openpyxl import Workbook
  5. from openpyxl import load_workbook
  6. from openpyxl.worksheet.datavalidation import DataValidation
  7. from openpyxl.utils.dataframe import dataframe_to_rows
  8. from openpyxl.styles import Border,PatternFill,Font
  9. import psycopg2
  10. # 数据拆分
  11. # 拆分生成新文件,设置数据有效性,设置表格样式,配置邮件发送
  12. #---------------------------------------------------------------------------
  13. #数据读取和清洗
  14. file_path = r'C:\Users\james\Desktop\运维数据\11111111' #设置根目录
  15. file_name = r'快递柜运力状态监控数据.xlsx' #设置excel文件名,一般为固定
  16. #①连接数据库并获取维表数据及清洗
  17. conn = psycopg2.connect(database="database",
  18. user="root",
  19. password="admin",
  20. host="localhost",
  21. port="443")
  22. cursor = conn.cursor()
  23. cursor.execute('select * from dim_city')
  24. df_city = pd.DataFrame(cursor.fetchall())
  25. df_city.columns = ['big_city_name','city_code','city_name','region']
  26. #②读取excel数据表及清洗
  27. path = file_path + '\\' + file_name
  28. df = pd.read_excel(path)
  29. df['城市'] = df['城市'].ffill() #对城市数据进行向下填充
  30. df.dropna(subset=['失联状态'],inplace=True) #删除掉非失联状态的数据
  31. #③两个数据合并,增加维度信息,以便后续数据拆分
  32. df_new= pd.merge(df,df_city,how='left',left_on = '城市',right_on = 'city_name')
  33. df['区域'] = df_new['region']
  34. df['失联原因'] = None
  35. cursor.close()
  36. #---------------------------------------------------------------------------
  37. #设置数据有效性规则
  38. dv = DataValidation(type="list", formula1='"测试机-内部、代理商测试,外部因素-断电、纠纷等,业务待开发-用户没上来、要转移,硬件问题,其他等"', allow_blank=True)
  39. # 设置错误信息提示
  40. dv.error ='你输入的内容不符合规范'
  41. dv.errorTitle = '非法的输入'
  42. # 设置提示信息
  43. dv.prompt = '请直接选择故障原因,勿修改表格表头结构'
  44. dv.promptTitle = '下拉选择'
  45. #---------------------------------------------------------------------------
  46. #设置边框颜色
  47. border = Border(left=Side(border_style='thin',color='000000'),
  48. right=Side(border_style='thin',color='000000'),
  49. top=Side(border_style='thin',color='000000'),
  50. bottom=Side(border_style='thin',color='000000'))
  51. #设置字体颜色
  52. font = Font(size=10, bold=True, name='微软雅黑', color="000000")#字体大小,加粗,字体名称,字体名字
  53. #设置背景颜色
  54. fill = PatternFill(patternType="solid", start_color="5B9BD5")#纯色填充
  55. #---------------------------------------------------------------------------
  56. for i in set(df_city.region.dropna()): #通过for循环拆分文件
  57. wb = Workbook()
  58. ws = wb.active
  59. df_i = df[df['区域']==i]
  60. df_i.reset_index(inplace=True,drop=True)
  61. for r in dataframe_to_rows(df_i, index=True, header=True):
  62. if len(r)!=1:
  63. ws.append(r)
  64. print('读取_'+i+'_数据完成!')
  65. c1 = 'R2'+':'+'R'+str(df_i.shape[0]+1)
  66. c2 = 'A1'+':'+'R'+str(df_i.shape[0]+1)
  67. dv.add(c1)
  68. ws.add_data_validation(dv) #给单元格添加数据验证
  69. for row in ws[c2]: #给单元格添加边框
  70. for cell in row:
  71. if cell.row == 1: #首行加粗,设置背景颜色
  72. cell.font = font
  73. cell.border = border
  74. cell.fill = fill
  75. cell.border = border
  76. wb.save(file_path + '\\' + file_name.split('.')[0]+'_'+i+'.xlsx')
  77. print('成功生成_'+i+'_失联快递柜数据!\n')
  78. # 设置数据有效性并根据地区拆分多个excel文件

脚本执行的结果,生成所需的文件数据,方便后续发送给各地区同事。

新数据增加一列失联原因,添加数据有效性验证,方便选择及规范数据。也方便后期核对数据。

第二步:邮件发送模块

  1. # email负责构造邮件,smtplib负责发送邮件
  2. # coding:utf-8
  3. # smtplib模块负责连接服务器和发送邮件
  4. # MIMEText:定义邮件的文字数据
  5. # MIMEImage:定义邮件的图片数据
  6. # MIMEMultipart:负责将文字图片音频组装在一起添加附件
  7. import smtplib # 加载smtplib模块
  8. from email.mime.text import MIMEText
  9. from email.utils import formataddr
  10. from email.mime.application import MIMEApplication
  11. from email.mime.image import MIMEImage
  12. from email.mime.multipart import MIMEMultipart
  13. from email import encoders
  14. sender = 'james.wang@baidu.com' # 发件人邮箱账号
  15. receive = 'harden.Li@baidu.com' # 收件人邮箱账号
  16. cc_mail = 'kurry.Lin@baidu.com,thompson.xiong@baidu.com' # 抄送邮箱账号
  17. passwd = 'james123'
  18. mailserver = 'smtp.baidu.com'
  19. port = '25'
  20. sub = '快递柜失联原因监控数据'
  21. try:
  22. msg = MIMEMultipart('related')
  23. msg['From'] = formataddr(["sender", sender]) # 发件人邮箱昵称、发件人邮箱账号
  24. msg['To'] = formataddr(["receiver", receive]) # 收件人邮箱昵称、收件人邮箱账号
  25. #msg['Cc'] = formataddr(["ccmail", cc_mail]) # 邮件抄送人
  26. msg['Cc'] = cc_mail
  27. msg['Subject'] = sub
  28. print('读取账号信息完成')
  29. #文本信息
  30. #txt = MIMEText('this is a test mail', 'plain', 'utf-8')
  31. #msg.attach(txt)
  32. #正文内容
  33. body = """
  34. <b>本周快递柜失联明细:</b><br></br>
  35. <!doctype html> <html><head> <meta charset="utf-8"></head>
  36. <body><div>
  37. <p>各位运维同事大家好,请认真填写选择快递柜失联原因,并于周四将数据提交数据分析同事,谢谢!:</P>
  38. </div> <style type="text/css">p{text-indent: 2em; /*首行字符缩进设置*/}</style>
  39. <span style="float:right;">数据分析:james</span>
  40. </body>
  41. </html>
  42. """
  43. text = MIMEText(body, 'html') #, 'utf-8'
  44. msg.attach(text)
  45. print('正文信息构建完成')
  46. path = file_path+'\\'+file_name
  47. #明细附件信息 ①
  48. attach = MIMEApplication(open(path,'rb').read(),encoding="utf8")
  49. attach.add_header('Content-Disposition', 'attachment', filename='filename.xls')
  50. msg.attach(attach)
  51. #明细附件信息 ②
  52. attach = MIMEApplication(open(path,'rb').read(),encoding="utf8")
  53. attach.add_header('Content-Disposition', 'attachment', filename='filename.xls')
  54. msg.attach(attach)
  55. print('附件添加成功')
  56. #发送邮件
  57. server = smtplib.SMTP(mailserver, port) # 发件人邮箱中的SMTP服务器,端口是25
  58. server.login(sender, passwd) # 发件人邮箱账号、邮箱密码
  59. server.sendmail(sender, receive.split(',')+cc_mail.split(','), msg.as_string()) # 发件人邮箱账号、收件人邮箱账号、发送邮件
  60. server.quit()
  61. print('邮件发送成功')
  62. except Exception as e:
  63. print(e)

将数据下发到各区域,由各地运维人员下载填写。

第三步:回收文件统计

  1. # 运维回收数据合并
  2. # 合并所有文件,统计所需字段数据
  3. path = file_path+'\\'+'回收数据'
  4. df = pd.DataFrame({'区域':[],'快递柜SN':[],'失联原因':[]})
  5. n=1
  6. for filename in os.listdir(path):
  7. if '汇总' not in filename:
  8. filename=path+"\\" + filename
  9. print('读取第%d个文件' %n,filename )
  10. data = pd.read_excel(filename)
  11. print('读取第%d个文件成功' %n)
  12. n = n + 1
  13. df = pd.concat([df,data],join='inner')
  14. df.drop_duplicates(subset='快递柜SN',keep='last',inplace = True) #防止各地区提交数据出现重复
  15. df.to_excel(path+"\\"+'汇总文件.xlsx',encoding='utf-8')
  16. print('\n')
  17. print(df['失联原因'].value_counts(),'\n')
  18. print(df['区域'].value_counts())
  19. df['失联原因'].value_counts().plot(kind = 'pie',figsize=(15,8),fontsize=12)

做简单的数据可视化展示~

运营层面来说,沟通总是最耗时间的,和几个大区的同事沟通新数据填写和收集流程,耗时接近3个小时。第一周数据通过手动汇总,耗时共40分钟。但业务流程定下来后,通过脚本触发,第二周直接邮件给到一线同事,催下大家提交数据结果,最后通过脚本合并,第二周耗时低于2分钟。效率提升几十倍还是有的。技术和运营能很好结合的话,带来的效率提升回报还是很丰厚的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/907502
推荐阅读
相关标签
  

闽ICP备14008679号