27

I was following the style guide for pandas and it worked pretty well.

How can I keep these styles using the to_html command through Outlook? The documentation seems a bit lacking for me.

(df.style
   .format(percent)
   .applymap(color_negative_red, subset=['col1', 'col2'])
   .set_properties(**{'font-size': '9pt', 'font-family': 'Calibri'})
   .bar(subset=['col4', 'col5'], color='lightblue'))

import win32com.client as win32
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.Subject = subject_name
mail.HTMLbody = ('<html><body><p><body style="font-size:11pt; 
font-family:Calibri">Hello,</p> + '<p>Title of Data</p>' + df.to_html(
            index=False, classes=????????) '</body></html>')
mail.send

The to_html documentation shows that there is a classes command that I can put inside of the to_html method, but I can't figure it out. It also seems like my dataframe does not carry the style that I specified up top.

If I try:

 df = (df.style
       .format(percent)
       .applymap(color_negative_red, subset=['col1', 'col2'])
       .set_properties(**{'font-size': '9pt', 'font-family': 'Calibri'})
       .bar(subset=['col4', 'col5'], color='lightblue'))

Then df is now a Style object and you can't use to_html.

Edit - this is what I am currently doing to modify my tables. This works, but I can't keep the cool features of the .style method that pandas offers.

email_paragraph = """
<body style= "font-size:11pt; font-family:Calibri; text-align:left; margin: 0px auto" >
"""

email_caption = """
<body style= "font-size:10pt; font-family:Century Gothic; text-align:center; margin: 0px auto" >
"""


email_style = '''<style type="text/css" media="screen" style="width:100%">
    table, th, td {border: 0px solid black;  background-color: #eee; padding: 10px;}
    th {background-color: #C6E2FF; color:black; font-family: Tahoma;font-size : 13; text-align: center;}
    td {background-color: #fff; padding: 10px; font-family: Calibri; font-size : 12; text-align: center;}
  </style>'''
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
trench
  • 5,075
  • 12
  • 50
  • 80
  • I tried for hours yesterday with no luck. I cannot figure out how to customize the dataframe in Outlook. It looks ugly (large font). The dataframe on my computer looks nice.. it highlights where the metric failed to meet the target, it has bar graphs to show the volume. Is there no way to get that to display on the outlook email? – trench Apr 28 '16 at 11:09

3 Answers3

47

Once you add style to your chained assignments you are operating on a Styler object. That object has a render method to get the html as a string. So in your example, you could do something like this:

html = (
    df.style
    .format(percent)
    .applymap(color_negative_red, subset=['col1', 'col2'])
    .set_properties(**{'font-size': '9pt', 'font-family': 'Calibri'})
    .bar(subset=['col4', 'col5'], color='lightblue')
    .render()
)

Then include the html in your email instead of a df.to_html().

Rakmo
  • 1,926
  • 3
  • 19
  • 37
dennisobrien
  • 1,148
  • 13
  • 7
  • 2
    Actually, I just noticed that the bar graphs are not showing up in the Outlook email. Everything else is working fine though. Any ideas how to get it to display? – trench Jun 20 '16 at 15:51
  • 1
    @trench Were you able to get Outlook showing the bars? I am having the same problem and this question here is the most relevant discussion I could find on the web.. – Kocas Jul 24 '20 at 15:24
3

It's not an extravagant / pythonic solution. I inserted the link to a direct css file before the html code made by the to_html () method, then I saved the whole string as an html file. This worked well for me.

dphtml = r'<link rel="stylesheet" type="text/css" media="screen" href="css-table.css" />' + '\n'
dphtml += dp.to_html()

with open('datatable.html','w') as f:
    f.write(dphtml)
Anton Frolov
  • 112
  • 1
  • 9
  • Unfortunately this will not work when mailing the html (as intended by the OP) as the css file cannot be referenced anymore by the receiver. – Robert Jan 20 '20 at 13:26
0

Selecting the table (the rendered, styled, dataframe widgets in jupyter) and copy-pasting to an email body worked for me (using outlook office).

No manual html extraction, saving, loading, or anything like that.

Michele Piccolini
  • 2,634
  • 16
  • 29