brno792
brno792

Reputation: 6799

Conditionally Apply In-Line Style Format to HTML Table with Python

I'm embedding a dataframe into an email's body as an html table. I want to conditionally format the cell colors and text colors based on the values in each cell.

I first read in some data from an example csv file and format it as an html table using the pandas to_html() method:

df = pd.read_csv('example.csv')
table = df.to_html()

Now I create some basic html with <style> tags for the message body and insert the table html code into a <div> in the body of the msg string as follows:

msg = """<html>
        <style type = "text/css">
            table, th, td { border: 1px solid black; }
        </style>
        <head></head>
        <body>
            <p>some text</p>
            <div> %s </div>
        </body
    </html>""" % (table)

I then convert the <style> css code to in-line styling using the premailer python module as such:

from premailer import transform
result = transform(msg)

Now result is a string of html with a table that has in-line styling like <table border="1" class="dataframe" style="border:1px solid black">

I embed the resulting html in the email with:

msg_body = MIMEText(result, 'html')
msg.attach(msg_body)

This all works great.

Now I need to conditionally format the cell colors and font colors based on the values in each cell.

How can I best do this? Was thinking some function such as:

def styleTable(x):
  if x < 0:
    return 'background-color: red'
  else
    return ''

But how can I apply this to my html string? Or do I need to do something different up-stream?

Again, this will be embedded in an email so cannot have Javascript or CSS code in it. Thanks

Upvotes: 5

Views: 5503

Answers (1)

pg2455
pg2455

Reputation: 5148

With the current development in pandas there is a functionality to modify the style of dataframe before converting it to HTML.

Simple solution is to define a function and pass it as a parameter to the apply function of style.

Here is an example:

def f(val):
   # @params: val is the entire column if axis is 0
   # @returns: css style attributes based on the cell value
   return ['color: red' if x < 0 else 'color: blue' for x in val]

html_style = df.style.apply(f, axis = 0, subset = ['column_name']) # this will apply the css style to td of that column

 # above only returns Styler object so you need to convert it to string to render it
html_style.render() # this does the job

You can read more about it here: http://pandas.pydata.org/pandas-docs/stable/style.html#Building-Styles

Upvotes: 2

Related Questions