0

I am working on a python project where I am needed to send a mail that contains some text and a dataframe. I need the dataframe to be added to the mail body as a table and not an attachment. The dataframe would not have more than 5-6 columns and 10-15 rows. No matter what I try, the dataframe is getting attached as an html file.

I am sorry for any lapses in the format of the question. Thanks in advance. I am using the below code right now :

'''

    from pretty_html_table import build_table
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    import smtplib
    
    
    email_df  = mail_df *(mail_df is the dataframe I need to send)
    
    mail_df.to_string(index=False)
    body1 = '''Dear Employee,

        Please find the below details. 
        Please confirm these entries and incase of any changes needed, Log in to - 
        abcd.com. 
        ''' +'\n\n'
    
    mail_df = mail_df[['IDNo','Value1','Value2','Value3']]

    host = "host.name.com"
    
    
    TO = "pqr@gmail.com"

    msg = MIMEMultipart()
    
    msg['Subject'] = "Mail Subject"
    msg['From'] = 'xyz@gmail.com'
    html = """\
            <html>
                <head></head>
                    <body>
                        {0}
                    </body>
            </html>
    """.format(mail_df.to_html(index=False))

    part1 = MIMEText(html, 'html')
    
    
    msg.attach(part1)


    server = smtplib.SMTP(host)
    server.starttls()
    server.sendmail(msg['From'], TO , msg.as_string())
    server.close()

'''

  • Does this answer your question? [Send HTML emails with Python](https://stackoverflow.com/questions/882712/send-html-emails-with-python) – Michael Butscher Jun 05 '23 at 06:28

2 Answers2

2

Try this:

import pandas as pd
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


# Convert DataFrame to HTML table
html_table = mail_df.to_html(index=False)

# Email configuration
sender_email = 'your_email@example.com'
receiver_email = 'recipient_email@example.com'
subject = 'Mail Subject'
smtp_server = 'smtp.example.com'
smtp_port = 587
#smtp_username = 'your_email@example.com'
#smtp_password = 'your_email_password'

# Construct the email
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = subject

start = 'Dear Employee,\n\nPlease find the below details.\nPlease confirm these entries and Log in to - abcd.com if any changes are needed.'

body = start + '\n\n' + html_table

html = f'<html lang="en">\n\t<head><\\head>\n\t<body>\n\t\t{body}\n\t<\\body>\n<\\html>'

# Attach the HTML table to the email body
msg.attach(MIMEText(html, 'html'))

# Connect to the SMTP server and send the email
try:
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.ehlo()
    server.starttls()
    #server.login(smtp_username, smtp_password)
    server.sendmail(sender_email, receiver_email, msg.as_string())
    server.close()
    print('Email sent successfully!')
except Exception as e:
    print('Something went wrong while sending the email.')
    print(e)

Bane
  • 99
  • 7
  • Thank you so very much. This was really helpful. Worked like a charm. I just had one issue. Got the head and body html tags as well in the mail. Working on removing that now. ''' <\head> Dear Employee, Please find the below details as entered by the Timesheet Recommendation Tool. Please confirm these entries and incase of any changes needed, Log in to - IDNo Value1 Value2 Value3 1 A B C ....... <\body> <\html> ''' – FarzadAvari Jun 05 '23 at 07:32
1

You could make it much simpler with the EmailMessage interface (around since Python 3.3)

from email.message import EmailMessage
import smtplib

# Write the header in HTML
body1 = '''<p>Dear Employee,</p>
    <p>Please find the below details.<br>
    Please confirm these entries and incase of any changes needed, Log in to abcd.com.</p>
'''


host = "host.name.com"

TO = "pqr@gmail.com"

msg = EmailMessage()

msg['Subject'] = "Mail Subject"
msg['From'] = 'xyz@gmail.com'
msg['To'] = TO

# write the header and the table in the same html bloc
html = """\
        <html>
            <head></head>
                <body>
                    {0}
                    {1}
                </body>
        </html>
""".format(body1, mail_df.to_html(index=False))

# set that html as the content of the message
msg.set_content(html, subtype='html')


server = smtplib.SMTP(host)
server.starttls()

# and send it...                        
server.send_message(msg)
server.close()
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252