Pythone :How to Use Dataframe Output in Email Body as Text

Pythone :How to use dataframe output in email body as Text

Consider pandas's DataFrame.to_html() which renders data fame to HTML table to be used in email's HTMLBody. If you do not specify a filename it will output table as a string.

...
mail.Subject = 'Madsaage Subject'

mail.HTMLBody = '''<h3>Please find data attached and below.</h3>
{}'''.format(Df.to_html())
...

Alternatively, use DataFrame.to_string() in the email's Body.

mail.Body = '''Please find data attached and below.\n\n
{}'''.format(Df.to_string())

Pandas send email containing dataframe as a visual table

Try:

  • Using str.format to append your DF html to the email body html.

Ex:

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


recipients = ['ToEmail@domain.com']
emaillist = [elem.strip().split(',') for elem in recipients]
msg = MIMEMultipart()
msg['Subject'] = "Your Subject"
msg['From'] = 'from@domain.com'


html = """\
<html>
<head></head>
<body>
{0}
</body>
</html>
""".format(df_test.to_html())

part1 = MIMEText(html, 'html')
msg.attach(part1)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.sendmail(msg['From'], emaillist , msg.as_string())

How to get a panda data frame from an output?

I guess I understand your problem, subject is a str and not a list. You have to learn how to collect the data in a list and pass this list to the pandas DataFrame. Then you can follow my comment and create a DataFrame using pandas. Please check the rough prototype below:

import pandas as pd

subject_list = []
from_list = []
date_list = []
for i in range(...):
# replace prints with list.append()

# print("Subject:", subject)
# print("From:", From)
# print("Date:", Date)
subject_list.append(subject)
from_list.append(From)
date_list.append(Date)

df = pd.DataFrame({"Subject": subject_list, "From": from_list, "Date": date_list})
print(df)

Email dataframes without and with Styling

The solution I came up with would look like this:

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
from premailer import transform

def send_email():
styler = (df_details.style.apply(highlight_same_week, axis=None).hide_index()).render()

msg = MIMEMultipart()
msg['Subject'] = "This is a test"
msg['From'] = 'abc@dfe.com'
msg['To'] = 'abc@dfe.com'

html = """
<html>
<head></head>
<body>
<p>Hello!<br>
<br>
Raw:<br>
{0}
<br>
Formated<br>
{1}
</p>
</body>
</html>
""".format(df.to_html(), styler)

html = transform(html)
part1 = MIMEText(html, 'html')
msg.attach(part1)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(the_user, the_password)
server.send_message(msg)
server.quit()

and highlight_same_week looks like this:

    def highlight_same_week(s):
return pd.DataFrame(df_template.values, columns=s.columns)

So df_details is the dataframe with the values I am interested to style while df_template is a dataframe with the same dimensions as df_details but its values are styling elements, for instance:

df_template.iloc[x, y] = 'background-color: #ffff00'

So the main points to fix/correct were:

  • using the right functions to create the styler variable (first line in the send_email function)
  • using a dataframe template with the desired styles (here I am only highlithing in yellow the row where two column values are within the same week, based on datetime.isocalendar())
  • tranform my raw HTML variable with the transform function from the premailer library

How do I send a styled pandas DataFrame by e-mail without losing the format?

I was able to find an answer to my question following this post: how to draw a beautiful colorful table with pandas or other package in Python?

Essentially, if you use the .set_table_styles to add the borders after adding the colors to the cells, the html code sent by e-mail will be displayed properly. I hope it helps anyone with the same issue.



Related Topics



Leave a reply



Submit