狂自私

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

python 使用smtp发送带附件的邮件

根据从网上搜索到的信息,我几乎是完成了发送邮件的主体过程,但是关于邮件附件的名称,让我陷入了难题,名称不被正确识别,并且部分邮件客户端还会不显示附件。

我知道大家不想看过程,我直接贴出解决方法:就是删除_header的第一个元素:

复制代码
def main():
    html_content = 组装邮件正文消息()
    # print(html_content)
    send_user = 'xxxx'
    receiver = ['xxxx']
    cc=['xxxx',]
    # message=MIMEText(html_content,'html','utf-8')
    message=MIMEMultipart()
    message['From']=Header(send_user,'utf-8')
    # message['To']=Header(receiver,'utf-8')
    message['To']=','.join(receiver)
    message['Cc']=','.join(cc)    #抄送
    #邮件主题
    subject="{}-xx装置-近24小时在线情况".format(datetime.datetime.now().strftime('%Y年%m月%d日'))
    message['Subject']=Header(subject,'utf-8')
    message.attach(MIMEText(html_content,'html','utf-8'))
    #附件
    file_path = 保存离线明细数据()
    part=MIMEText(open(file_path,'rb').read(),'base64','utf-8')
    #↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓关键↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    del part._headers[0]
    #↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    #↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑然后解释下为啥要删除,因为它默认就生成了Content-Type属性,位于最前面,邮件客户端在读取的时候会发现两个Content-Type,会合并在一起并且对其进行解码,然后就会解码错误,有些客户端会给一个默认名称,ATT001之类,有些客户端根本不显示出来。

    part.add_header('Content-Disposition','attachment', filename=f"{os.path.basename(file_path)}")
    part.add_header('Content-Type','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', name=f'{os.path.basename(file_path)}')
    #↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑我发送的是xlsx表格,我从邮件客户端将邮件原文下载下来,用文本编辑器打开发现它是使用这个类型。
    message.attach(part)

    smtobj=smtplib.SMTP()
    smtobj.connect('smtp.sc.sgcc.com.cn',25)
    smtobj.login('gwscdky-gy-ztjc@sc.sgcc.com.cn','abcd-1235')
    to_addrs=receiver+cc
    smtobj.sendmail(send_user,to_addrs,message.as_string())
if __name__ == "__main__":
    main()
复制代码
复制代码
  1 def 构造table_html代码(在线率数据:list)->str:
  2     html_table='''\n    <table>
  3         <tr>
  4             <th rowspan="2" class="tb_chinese">序号</th>
  5             <th rowspan="2" class="tb_chinese">单位</th>
  6             <th colspan="3" class="tb_chinese">输电</th>
  7             <th colspan="3" class="tb_chinese">配电</th>
  8         </tr>
  9         <tr>
 10             <th class="tb_chinese">装置数</th>
 11             <th class="tb_chinese">在线数</th>
 12             <th class="tb_chinese">在线率</th>
 13             <th class="tb_chinese">装置数</th>
 14             <th class="tb_chinese">在线数</th>
 15             <th class="tb_chinese">在线率</th>
 16         </tr>\n'''
 17     idx=1
 18     for data in 在线率数据:
 19         try:
 20             data[3] = "{:.2f}".format(float(data[3]))
 21             data[3]=str(data[3])+'%'
 22         except Exception as e:
 23             pass
 24         try:
 25             data[6] = "{:.2f}".format(float(data[6]))
 26             data[6]=str(data[6])+'%'
 27         except Exception as e:
 28             pass
 29         if(data[0] != '总计'):
 30             code_line = """        <tr>
 31                 <td class="tb_number">{}</td><td class="tb_chinese">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td>
 32             </tr>\n""".format(idx,data[0],data[1],data[2],data[3],data[4],data[5],data[6])
 33             idx+=1
 34         else:
 35             code_line = """        <tr>
 36                 <td colspan="2" class="tb_chinese">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td><td class="tb_number">{}</td>
 37             </tr>\n""".format(data[0],data[1],data[2],data[3],data[4],data[5],data[6])
 38         html_table+=code_line
 39     html_table+='</table>\n'
 40     return html_table;
 41 def 组装邮件正文消息():
 42     在线率数据=重整在线率列表(获取在线率数据())
 43     总计=  在线率数据[-1]
 44     总体情况="""<p class="chinese">截至{}<span class="number">14</span>点整,输配电线路共计接入导线覆冰检测装置<span class="number">{}</span>套,输电在线率为<span class="number">{:.2f}%</span>""".format(datetime.datetime.now().strftime("<span class=\"number\">%Y</span>年<span class=\"number\">%m</span>月<span class=\"number\">%d</span>日"),(int(总计[1])+int(总计[4])),float(总计[3]))
 45     主网_确定是否有低于百分之九十的地市=确定是否有低于百分之九十的地市(在线率数据,False)
 46     if(not 主网_确定是否有低于百分之九十的地市[0]):
 47         总体情况+=''
 48     else:
 49         总体情况+=",{}在线率较低。".format("".join([data[0] for data in 主网_确定是否有低于百分之九十的地市[1]]))
 50     配网_确定是否有低于百分之九十的地市=确定是否有低于百分之九十的地市(在线率数据,True)
 51     if(not 配网_确定是否有低于百分之九十的地市[0]):
 52         总体情况+='配电在线率为<span class="number">{:.2f}%<span>。'.format(float(总计[-1]))
 53     else:
 54         总体情况+='配电在线率为<span class="number">{:.2f}%<span>,{}在线率较低。'.format(float(总计[-1]),"".join([data[0] for data in 配网_确定是否有低于百分之九十的地市[1]]))
 55     在线率数据_html=构造table_html代码(在线率数据)
 56     html_content="""
 57 <html>
 58     <head>
 59         <style>
 60             h1 {{
 61                 font-family: "SimHei", "Arial", sans-serif; /* 黑体(SimHei) */
 62                 font-size: 16pt; /* 三号字体 */
 63                 font-weight: bold;  /* 加粗 */
 64                 text-align: left;
 65             }}
 66             p{{
 67                 font-size: 16pt; /* 三号字体 */
 68                 text-indent: 4em;   /* 缩进2字符 */
 69             }}
 70             .chinese {{
 71                 font-family: "FangSong", "仿宋", serif; /* 仿宋 */
 72                 font-size: 16pt; /* 三号字体 */
 73                 text-indent: 2em;   /* 缩进2字符 */
 74             }}
 75             /* 控制英文和数字的字体 */
 76             .number {{
 77                 font-family: "Times New Roman", Times, serif; /* Times New Roman */
 78                 font-size: 16pt; /* 三号字体 */
 79             }}
 80             .tb_chinese {{
 81                 font-family: "FangSong", "仿宋", serif; /* 仿宋 */
 82                 font-size: 12pt; /* 小四字号 */
 83                 font-weight: normal;  /* 常规 */
 84             }}
 85             .tb_number {{
 86                 font-family: "Times New Roman", Times, serif; /* Times New Roman */
 87                 font-size: 12pt; /* 小四字号 */
 88             }}
 89             table {{
 90                 border-collapse: collapse; /* 边框合并 */
 91                 width: auto; /* 自动调整宽度 */
 92                 margin-left: 0; /* 左对齐 */
 93             }}
 94             th, td {{
 95                 border: 1px solid #ccc; /* 边框宽度 */
 96                 text-align: center; /* 水平居中 */
 97                 padding: 5px;    /* 内边距 */
 98                 vertical-align: middle; /* 垂直居中 */
 99             }}
100         </style>
101     </head>
102     <body>
103         <h1>一、总体情况</h1>
104         <!-- 总体情况  -->
105         {}
106         <br>
107         {}
108         <br>
109         <h1>二、离线装置明细</h1>
110         <p class="chinese">装置离线明细请见附件。</p>
111         <br>
112     </body>
113     </html>
114 """.format(总体情况,在线率数据_html)
115     return html_content;
View Code
复制代码

 

posted on   狂自私  阅读(91)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示