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
How to Locate Elements on Webpage With Headless Chrome
How to Split a CSV File Row to Columns in Python
Creating Random Pairs from Lists
Pandas: Calculate Total Percent Difference Between Two Data Frames
Sum a Column Based on Groupby and Condition
How to Simply Add a Column Level to a Pandas Dataframe
Python Works in Pycharm But Not from Terminal
Plot Line Graph from Pandas Dataframe (With Multiple Lines)
Django - How to Retrieve Data in Database in Dropdownlist
Selenium Python Send_Key Error: List Object Has No Attribute
Pandas Dataframe Check If Column Value Exists in a Group of Columns
Retrieving Subfolders Names in S3 Bucket from Boto3
How to Test Multiple Variables for Equality Against a Single Value
How to Prevent Brokenpipeerror When Doing a Flush in Python
Python Tkinter How to Update a Text Widget in a for Loop