17

I am trying to send multiple dataframes as tables in an email. Using df.to_html() I am able to render a HTML string for the table which I am attaching as the part of the email body. I am successfully able to get the tables in the email.

html.append(table.to_html(na_rep = " ",index = False))
body = '\r\n\n<br>'.join('%s'%item for item in html)
msg.attach(MIMEText(body, 'html'))

But how do I add background color to the header of these tables?

2
  • 3
    Look into pandas.DataFrame.style. There is a set_table_styles you can use to set your HTML attributes and then you can use the .render() method to get the HTML script. Commented Jan 3, 2017 at 15:20
  • @Abdou Can you provide an example as to how do we give the proper attributes in set_table_styles. I am relatively new with HTML and CSS Commented Jan 3, 2017 at 16:46

2 Answers 2

27

You can try doing this in two ways:

With set_table_styles from pandas.DataFrame.style:

import pandas as pd
import numpy as np

# Set up a DataFrame
np.random.seed(24)
df = pd.DataFrame({'A': np.linspace(1, 10, 10)})
df = pd.concat([df, pd.DataFrame(np.random.randn(10, 4), columns=list('BCDE'))],
               axis=1)
df.iloc[0, 2] = np.nan


df_html_output = df.style.set_table_styles(
    [{'selector': 'thead th',
    'props': [('background-color', 'red')]},
    {'selector': 'thead th:first-child',
    'props': [('display','none')]},
    {'selector': 'tbody th:first-child',
    'props': [('display','none')]}]
).render()

html.append(df_html_output)
body = '\r\n\n<br>'.join('%s'%item for item in html)
msg.attach(MIMEText(body, 'html'))

Or with .to_html:

df_html_output = df.to_html(na_rep = "", index = False).replace('<th>','<th style = "background-color: red">')

html.append(df_html_output)
body = '\r\n\n<br>'.join('%s'%item for item in html)
msg.attach(MIMEText(body, 'html'))

The second one provides the option of removing the index column during the export (to_html) without having to do too much HTML tweaking; so it may be more suited to your needs.

I hope this proves useful.

Sign up to request clarification or add additional context in comments.

1 Comment

It seems set_table_styles doesnt work on gmail since it adds a separate <styles> tag above the <table> and gmail clips it off. to_html works but then it seems we cant use complicated selectors there.
4

I would recommend using Jinja2 for convenient HTML formatting. Just create a word document, add two lines {{Header}} with whatever background colour you would like, {{DF}}, add a page break and save this as html. Now use Jinja2 to render the templates. Below is a sample code of how Jinja2 can be used:

from jinja2 import Environment, FileSystemLoader
import StringIO
import pandas as pd

Template_Path = '/home/test/'
DF = [pd.DataFrame()]*5 # List of Dataframes
Header_Text = ['header']*5 # list of headers
env = Environment(loader=FileSystemLoader(Template_Path))
template = env.get_template('PDF_Temp.html') # name of your html template

Master_HTML = ''
for x in range(len(DF)):
    buf = StringIO.StringIO()
    DF_HTML = DF[x].to_html(buf)
    template_vars = {"Header"         : Header_Text[x]  ,
                     "DF"             : buf.getvalue()
                    }

    # Create PDF
    Master_HTML += template.render(template_vars) 

FN = 'test.html'
with open(FN, "w") as f:
    f.write(Master_HTML.encode('utf-8') )

This is a nice tutorial on Jinja2: http://pbpython.com/pdf-reports.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.