user2023
user2023

Reputation: 478

How to attched pandas dataframe as CSV over the e-mail using smtplib

I am working with a pandas Dataframe which works fine however i want that DataFrame to create csv file using df.to_csv and attach that to an e-mail So, that recipient can have that as an attachment as well as html, df.to_html work good.

How i could attach df.to_csv in an e-mail where i want html view to be intacted.

Below is the code part sample which I am using for sending an e-mail.

import smtplib
import pandas as pd
from tabulate import tabulate
from email.message import EmailMessage
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText

# mail vars
SMTP_SERVER = '[email protected]'
FROM = '[email protected]'
TO = ['[email protected]']
SUBJECT = 'test attachment e-mail'
EMAIL_TEMPLATE = """\
<html>
  <head>
  <style>
  table, th, td {{font-size:9pt; border:1px solid black; border-collapse:collapse; text-align:left; background-color:LightGray;}}
  th, td {{padding: 5px;}}
  </style>
  </head>
  <body>
     Dear Team,<br><br>
     Please Find the Project-wise Report with their respectove Owners ID and e-mail address.!<br><br>
     {} <br><br>
    Kind regards.<br>
    STR TEAM.
  </body>
</html>"""

DataFrame:

df = pd.DataFrame("/tmp/fix.txt")

Function to sen mail:

def send_email():
    server = smtplib.SMTP(SMTP_SERVER)
    msg = EmailMessage()
    msg['Subject'], msg['From'], msg['To'] = SUBJECT, FROM, TO
    msg.set_content("Text version of your html template")
    msg.add_alternative(
        EMAIL_TEMPLATE.format(df.to_html(index=False)),
        subtype='html'
    )
    server.send_message(msg)


if __name__ == '__main__':
    send_email()

Trial:

I tried using below but didn't work....

msg.add_alternative(EMAIL_TEMPLATE.format(df.to_csv(index=False)),subtype='csv')

Upvotes: 0

Views: 542

Answers (1)

Timeless
Timeless

Reputation: 37827

You need to use io.StringIO so can you attach the dataframe as a .csv.

Try this :

import smtplib
import pandas as pd
from tabulate import tabulate
from email.message import EmailMessage
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
import io

# mail vars
SMTP_SERVER = '[email protected]'
FROM = '[email protected]'
TO = ['[email protected]']
SUBJECT = 'test attachment e-mail'
EMAIL_TEMPLATE = """\
<html>
  <head>
  <style>
  table, th, td {{font-size:9pt; border:1px solid black; border-collapse:collapse; text-align:left; background-color:LightGray;}}
  th, td {{padding: 5px;}}
  </style>
  </head>
  <body>
     Dear Team,<br><br>
     Please Find the Project-wise Report with their respectove Owners ID and e-mail address.!<br><br>
     {} <br><br>
    Kind regards.<br>
    STR TEAM.
  </body>
</html>"""

def df_to_csv(df):
    with io.StringIO() as buffer:
        df.to_csv(buffer)
        return buffer.getvalue()

def send_email():    
    multipart = MIMEMultipart()
    multipart['Subject'],  multipart['From'], multipart['To'] = SUBJECT, FROM, TO
    attachment = MIMEApplication(df_to_csv(df))
    attachment['Content-Disposition'] = 'attachment; filename="dataframe.csv"'
    multipart.attach(attachment)
    multipart.attach(MIMEText(EMAIL_TEMPLATE, 'html'))
    server = smtplib.SMTP(SMTP_SERVER)
    server.sendmail(FROM, TO, multipart.as_string())
    server.quit()

if __name__ == '__main__':
    send_email()

Upvotes: 1

Related Questions