Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embed Pandas df html table in email using python 3

I am trying to embed and send html table created with pandas .to_html.

I'm happy to either send the df directly to the email or from a file.

So far I can embed images with the following:

fp = open(attachment, 'rb')                                                    
img = MIMEImage(fp.read())
fp.close()
img.add_header('Content-ID', '<{}>'.format(attachment))
msg.attach(img)

I have experimenting with this which attached the df but not embeds for some reason.

fp = open(att1, 'r')                                                    
img = MIMEText(fp.read(),'html')
fp.close()
img.add_header('Content-ID', '<att1>')
msg.attach(img)

Alternatively i can send the df data to an email but sends as unformatted text and can't seems to work out this approach with formatting (i.e.) table with simple border.

df = dFrame(q2) 
tbl = '{df}'
tbl = df.to_html(index=False,justify='center')
msgText = MIMEText('<b>%s</b><br><html src="cid:%s"><br>' % (body, tbl), 'html')
msg.attach(msgText)

More complete code for embedded image which i desire to adjust for embed html tables.

def sndFile1():
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.image import MIMEImage

    att1 = path + 'df.html'
    att2 = path + 'Indices.png'
    att3 = path + 'Segments.png'

    subject = 'Market Update'
    body = 'This Weeks Report'

    msg = MIMEMultipart()
    msg["To"] = myEml
    msg["From"] = myEml
    msg["Subject"] = subject

    msgText = MIMEText('<b>%s</b><br><html src="cid:%s"><img src="cid:%s"><img src="cid:%s"><br>' % (body, att1, att2, att3), 'html')
    msg.attach(msgText)

    fp = open(att1, 'r')                                                    
    img = MIMEText(fp.read(),'html')
    fp.close()
    img.add_header('Content-ID', '<att1>')
    msg.attach(img)

    fp = open(att2, 'rb')                                                    
    img = MIMEImage(fp.read())
    fp.close()
    img.add_header('Content-ID', '<{}>'.format(att2))
    msg.attach(img)

    fp = open(att3, 'rb')                                                    
    img = MIMEImage(fp.read())
    fp.close()
    img.add_header('Content-ID', '<{}>'.format(att3))
    msg.attach(img)

    s = smtplib.SMTP_SSL(mySMTP, smtpPORT)
    s.login(myUID,myPASS)
    s.sendmail(myEml,myRec, msg.as_string())

...and here's my final code with some minor tweaks to msgText based on solution from all working great! thanks

def sndFile1():
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.image import MIMEImage

    att1 = path + 'df.html'
    att2 = path + 'Indices.png'
    att3 = path + 'Segments.png'
    subject = 'Market Update'
    body = 'This Weeks Report'

    msg = MIMEMultipart()
    msg["To"] = myEml
    msg["From"] = myEml
    msg["Subject"] = subject

    fp = open(att1, 'r')                                                   
    html = fp.read()
    fp.close()

    msgText = MIMEText('<b>%s</b><br><%s><br><img src="cid:%s"><br><img src="cid:%s"><br>' % (body, html, att2, att3), 'html')
    msg.attach(msgText)

    with open(att2, 'rb') as fp:
        img = MIMEImage(fp.read())
    img.add_header('Content-ID', '<{}>'.format(att2))
    msg.attach(img)

    with open(att3, 'rb') as fp:                                                   
        img = MIMEImage(fp.read())
    img.add_header('Content-ID', '<{}>'.format(att3))
    msg.attach(img)

    s = smtplib.SMTP_SSL(mySMTP, smtpPORT)
    s.login(myUID,myPASS)
    s.sendmail(myEml,myRec, msg.as_string())
    s.quit()
like image 581
bassmann Avatar asked Aug 07 '18 11:08

bassmann


1 Answers

I modified snippet you provided. Main change was not using html dataframe as attachment but just insert it in message body.

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

with open('df.html', 'w') as fil:
    df.head().to_html(fil)

att1 = 'df.html'
att2 = path + 'Indices.png'
att3 = path + 'Segments.png'
subject = 'Market Update'
body = 'This Weeks Report'

msg = MIMEMultipart('alternative')
msg["To"] = myEml
msg["From"] = myEml
msg["Subject"] = subject

with open(att1, 'r') as fp:                                                    
    html = fp.read()

msgText = MIMEText('<b>%s</b><br>%s<img src="cid:%s"><br><img src="cid:%s"><br>' % (body, html, att2, att3), 'html')
msg.attach(msgText)

with open(att2, 'rb') as fp:
    img = MIMEImage(fp.read())
img.add_header('Content-ID', '<{}>'.format(att2))
msg.attach(img)

with open(att3, 'rb') as fp:                                                   
    img = MIMEImage(fp.read())
img.add_header('Content-ID', '<{}>'.format(att3))
msg.attach(img)

s = smtplib.SMTP_SSL(mySMTP, smtpPORT)
s.ehlo()
s.starttls()
s.login(username,password)
s.sendmail(me,you, msg.as_string())
s.quit()
like image 88
Kamil Niski Avatar answered Nov 14 '22 23:11

Kamil Niski