简体   繁体   English

如何将 Python 数据帧存储在内存中并将其作为 excel 附件发送到特定的电子邮件地址?

[英]How do I store Python dataframe in-memory and send it as excel attachment to specific email addresses?

I read my data from mongo dB and create a report.我从 mongo dB 读取数据并创建报告。 I used to save the report as a .xlsx file on my local machine and manually send it using email.我曾经将报告保存为本地计算机上的 .xlsx 文件,然后使用电子邮件手动发送。 I would like to automate this process.我想自动化这个过程。

I found a way in Python 3 to save the file in-memory using Python's io.BytesIO() functionality.我在 Python 3 中找到了一种使用 Python 的 io.BytesIO() 功能将文件保存在内存中的方法。 I tried a few things that I found on stack overflow but it didn't work for me.我尝试了一些在堆栈溢出时发现的东西,但它对我不起作用。 I would like to get some suggestions on how I can automate my work.我想就如何自动化我的工作获得一些建议。

Following is what I have tried,以下是我尝试过的,

df = pd.dataframe(df) # has my reports dataframe

def export_excel(df):
    with io.BytesIO() as buffer:
        writer = pd.ExcelWriter(buffer)
        df.to_excel(writer)
        writer.save()
        return buffer.getvalue()

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib

SEND_FROM = 'myemail@company.com'
EXPORTERS = {'dataframe.csv': export_csv, 'dataframe.xlsx': export_excel}

def send_dataframe(send_to, subject, body, df):
    multipart = MIMEMultipart()
    multipart['From'] = SEND_FROM
    multipart['To'] = 'myemail@company.com'
    multipart['Subject'] = subject
    for filename in EXPORTERS:    
        attachment = MIMEApplication(EXPORTERS[filename](df))
        attachment['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
        multipart.attach(attachment)
    multipart.attach(MIMEText(body, 'html'))
    s = smtplib.SMTP('localhost')
    s.sendmail(SEND_FROM, send_to, multipart.as_string())
    s.quit()

I do not get an error but don't get an email with an excel attachment too.我没有收到错误消息,但也没有收到带有 Excel 附件的电子邮件。

I need to solve the same topic, so here is my code:我需要解决相同的主题,所以这是我的代码:

import io
import pandas as pd 
from pandas import util

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib

df = util.testing.makeDataFrame()
# df.head()

output = io.BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
output.seek(0)

send_from = 'my_gmail@gmail.com'
gmail_pwd = 'my_gmail_password'
send_to = 'my_gmail@gmail.com'
subject = 'Daily report'
body = "<p>Please find attached report,<br/>by me</p>"
report_name = "report.xlsx"

msg = MIMEMultipart()
msg['Subject'] = subject  # add in the subject
msg['From'] = send_from
msg['To'] = send_to
msg.attach(MIMEText(body, 'html'))  # add text contents
file = MIMEApplication(output.read(), name=report_name)
file['Content-Disposition'] = f'attachment; filename="{report_name}"'
msg.attach(file)

smtp = smtplib.SMTP('smtp.gmail.com:587')
smtp.ehlo()
smtp.starttls()
smtp.login(send_from, gmail_pwd)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.quit()

Here is a snippet of my code where I was taking a dataframe then convert it to StringIO() to send it as a spreadsheet format.这是我的代码片段,我在其中获取数据帧,然后将其转换为 StringIO() 以将其作为电子表格格式发送。 Only difference is I am sending a csv file instead of xlsx.唯一的区别是我发送的是 csv 文件而不是 xlsx。 Hope it helps.希望能帮助到你。

textStream = StringIO()
dataframe.to_csv(textStream,index=False)

message = MIMEMultipart()
message['Subject'] = "Given Subject"

message.attach(MIMEApplication(textStream.getvalue(), Name="Name of the 
file"))

context = ssl.create_default_context()

with smtplib.SMTP(SMTP_host, SMTP_port) as server:
    server.starttls(context=context)
    server.login("mail user", "mail password")
    server.sendmail("mail user", "receiver email", message.as_string().encode('utf-8'))
    server.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM