Python 将数据框作为附件发送电子邮件

Python 将数据框作为附件发送电子邮件,python,pandas,email,smtp,mime,Python,Pandas,Email,Smtp,Mime,我正在尝试创建一个功能,可以发送一封带有数据框的电子邮件,该数据框作为csv文件附加。附加文件通常需要先将文件保存到磁盘,所以我不知道是否有任何直接的方法可以做到这一点 我创建了一个可以将数据框作为HTML附加的函数,也创建了一个可以将附件作为电子邮件发送的函数,但不能直接将数据框作为附加文件发送 常规设置 从email.mime.application导入MIMEApplication 从email.mime.multipart导入MIMEMultipart 从email.mime.text导

我正在尝试创建一个功能,可以发送一封带有数据框的电子邮件,该数据框作为
csv
文件附加。附加文件通常需要先将文件保存到磁盘,所以我不知道是否有任何直接的方法可以做到这一点

我创建了一个可以将数据框作为HTML附加的函数,也创建了一个可以将附件作为电子邮件发送的函数,但不能直接将数据框作为附加文件发送

常规设置

从email.mime.application导入MIMEApplication
从email.mime.multipart导入MIMEMultipart
从email.mime.text导入MIMEText
导入smtplib
导入操作系统
_服务器='我的服务器'
_端口=9999
_发送者='我的。email@domain.com'
def创建简单邮件(收件人、标题):
mail=MIMEMultipart()
邮件['Subject']=标题
邮件['To']=To
邮件['From']=\u发件人
以html格式发送数据帧

def mail_dataframe_as_html(to、msg、title、df):
邮件=创建简单邮件(收件人、消息、标题)
html_str=msg
html_str+=''
html_str+=df.to_html()
mail.attach(MIMEText(html_str,'html'))
smtp\u连接=smtplib.smtp(\u服务器,\u端口,超时=120)
smtp_connection.sendmail(_sender,to,mail.as_string())
发送附件

def将文件附加到邮件(邮件,f):
以开放式(f,“rb”)作为fil:
part=MIMEApplication(fil.read(),Name=os.path.basename(f))
部分['Content-Disposition']='附件;filename=“%s”“%os.path.basename(f)
邮件附件(部分)
回信
def mail_html(收件人、标题、html、附件=无):
mail=create\u simple\u mail(to=to,msg=None,title=title)
mail.attach(MIMEText(html,'html'))
如果附件不是无:
对于附件中的f:
邮件=将文件附加到邮件(邮件,f)
smtp\u连接=smtplib.smtp(\u服务器,\u端口,超时=120)
smtp_connection.sendmail(_sender,to,mail.as_string())
尝试使用
示例。
使用熊猫数据框作为.csv附件发送邮件:

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import os
import pandas as pd
from datetime import datetime

_server = 'smtp.example.com'
_port = 587
_sender = 'some_sender@example.com'
_pass = 'pass_value'

def create_simple_mail(to, title):
    mail = MIMEMultipart()
    mail['Subject'] = title
    mail['To'] = to
    mail['From'] = _sender
    return mail

def attach_file_to_mail(mail,f):
    with open(f, "rb") as fil:
        part = MIMEApplication(fil.read(), Name=os.path.basename(f))
        part['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(f)
        mail.attach(part)
    return mail

def mail_html(to, title, html, attachments=None):
    mail = create_simple_mail(to=to, title=title)
    mail.attach(MIMEText(html, 'html'))
    if attachments is not None:
        for f in attachments:
            mail = attach_file_to_mail(mail,f)
    
    smtp_connection = smtplib.SMTP(_server, _port, timeout=120)
    

    # I tested with TLS server connection
    smtp_connection.ehlo()
    smtp_connection.starttls()
    smtp_connection.ehlo()
    smtp_connection.login(_sender, _pass)

    smtp_connection.sendmail(_sender, to, mail.as_string())


if __name__ == "__main__":

    df_data = {'num': [1, 2, 3],
        'name': ['some val 1','some val 2','some val 3'],
        'year': [2001, 2002, 2003],
        
        }

    df = pd.DataFrame(df_data, columns = ['num', 'name','year'])

    now = datetime.now() 
    date_time = now.strftime("%d_%m_%Y__%H_%M_%S")
    file_name = f'{date_time}.csv'
    df.to_csv(file_name, index = False)

    mail_html('some@example.com','Some title','<b>html text</b>',[file_name])

    # If need
    os.remove(file_name)
从email.mime.application导入MIMEApplication
从email.mime.multipart导入MIMEMultipart
从email.mime.text导入MIMEText
导入smtplib
导入操作系统
作为pd进口熊猫
从日期时间导入日期时间
_服务器='smtp.example.com'
_端口=587
_发件人='一些_sender@example.com'
_通过='通过值'
def创建简单邮件(收件人、标题):
mail=MIMEMultipart()
邮件['Subject']=标题
邮件['To']=To
邮件['From']=\u发件人
回信
def将文件附加到邮件(邮件,f):
以开放式(f,“rb”)作为fil:
part=MIMEApplication(fil.read(),Name=os.path.basename(f))
部分['Content-Disposition']='附件;filename=“%s”“%os.path.basename(f)
邮件附件(部分)
回信
def mail_html(收件人、标题、html、附件=无):
邮件=创建简单邮件(收件人=收件人,标题=标题)
mail.attach(MIMEText(html,'html'))
如果附件不是无:
对于附件中的f:
邮件=将文件附加到邮件(邮件,f)
smtp\u连接=smtplib.smtp(\u服务器,\u端口,超时=120)
#我测试了TLS服务器连接
smtp_connection.ehlo()
smtp_连接。starttls()
smtp_connection.ehlo()
smtp\u连接。登录(\u发件人,\u通行证)
smtp_connection.sendmail(_sender,to,mail.as_string())
如果名称=“\uuuuu main\uuuuuuuu”:
df_data={'num':[1,2,3],
'name':['some val 1','some val 2','some val 3'],
"年份:[2001,2002,2003],,
}
df=pd.DataFrame(df_数据,列=['num','name','year']))
now=datetime.now()
日期\u时间=现在.strftime(“%d\u%m\u%Y\u%H\u%m\u%S”)
文件名=f'{date\u time}.csv'
df.to_csv(文件名,索引=False)
邮件(html)some@example.com“,”一些标题“,”html文本“,[文件名])
#必要时
删除(文件名)
结果:

我想出了一个非常好的解决方案,使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来清理可以附加到电子邮件的临时生成的文件

导入操作系统
导入uuid
类CreateAttachments:
def uuu init uuuu(self,dfs,file_names=None):
self.\u附件=dfs
#如果未指定通用文件名,则创建通用文件名
如果文件名为“无”:
self._name=[f'attached_df{i}.csv'表示范围内的i(len(dfs))]
#确保所有文件名以.csv扩展名结尾
其他:
self._name=[fn如果fn.endswith('.csv'),则为fn+'.csv'表示文件_name中的fn]
#如果提供的文件名少于附件,则会附加通用名称
如果len(self.\u名称)