Dataframe styling through Python

Viewed 10429

I am trying to send outlook mail via python. I import some data from excel files using dataframe and after some filtering I send them where the body of the mail is:

    body = '<html><body>'+df.to_html()+'</body></html>'

I get a table but the cells are not aligned.I can not use justify='left/write' as I want the cells to be center aligned,not just the column headers. I have used styles but it did not work either:

df.style.set_properties(subset=df.columns,**{'width':'10em', 'text-align':'center'})\

I tried this too and it did not work.

p=HTML(df.to_html(classes= 'table text-align:center'))

After surfing through similar problems I found another solution:

s = df.style.set_properties(**{'text-align': 'center'})
s.render()

However it makes the border of the table disappear.So I modified it:

s = df.style.set_properties(**{'text-align': 'center','border-color':'Black','border-width':'thin','border-style':'dotted'})

This gives border to the cells. But it looks like each cell is inside individual textbox,not like a table. How do I get this done?

The final result looks like this:

2 Answers

You need to style td and th elements of your table.

style_td = dict(selector="td", props=[('border-collapse', 'collapse')])

style_th = dict(selector="th", props=[('border-collapse', 'collapse')])

After that you can put this dicts to your dataframe.style.set_table_styles part. Like;

df_styled = df.style.set_table_styles([style_td, style_th])

It works for me. And also you can add more CSS option props to your each HTML element.

You can exactly do that without much editing, you only have to add:

'border-collapse':'collapse'

html = df[['Column 1','Column 2',]].style.hide_index().set_properties(**{'font-size': '11pt','background-color': '#edeeef','border-color': 'black','border-style' :'solid' ,'border-width': '0px','border-collapse':'collapse'}).applymap(style1,subset = 'Column 1').applymap(Style2 ,subset = 'Column 2').render()

NOTE : You can ignore the other parts of this above code-snipet , only useful thing is - - 'border-collapse':'collapse'

So now the border inside border will be resolved to only one border

A simple single line border

Related