add excel file attachment when sending python email
I found an easy way to do it using what Corey Shafer explains in this video on sending emails with python.
import smtplib
from email.message import EmailMessage
SENDER_EMAIL = "[email protected]"
APP_PASSWORD = "xxxxxxx"
def send_mail_with_excel(recipient_email, subject, content, excel_file):
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = SENDER_EMAIL
msg['To'] = recipient_email
msg.set_content(content)
with open(excel_file, 'rb') as f:
file_data = f.read()
msg.add_attachment(file_data, maintype="application", subtype="xlsx", filename=excel_file)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(SENDER_EMAIL, APP_PASSWORD)
smtp.send_message(msg)
Here is just a slight tweak on SoccerPlayer's post above that got me 99% of the way there. I found a snippet Here that got me the rest of the way. No credit is due to me. Just posting in case it helps the next person.
file = 'File.xlsx'
username=''
password=''
send_from = ''
send_to = 'recipient1 , recipient2'
Cc = 'recipient'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Cc'] = Cc
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = ''
server = smtplib.SMTP('smtp.gmail.com')
port = '587'
fp = open(file, 'rb')
part = MIMEBase('application','vnd.ms-excel')
part.set_payload(fp.read())
fp.close()
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename='Name File Here')
msg.attach(part)
smtp = smtplib.SMTP('smtp.gmail.com')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(',') + msg['Cc'].split(','), msg.as_string())
smtp.quit()
This is the code that worked for me- to send an email with an attachment in python
#!/usr/bin/python
import smtplib,ssl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
def send_mail(send_from,send_to,subject,text,files,server,port,username='',password='',isTls=True):
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = subject
msg.attach(MIMEText(text))
part = MIMEBase('application', "octet-stream")
part.set_payload(open("WorkBook3.xlsx", "rb").read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="WorkBook3.xlsx"')
msg.attach(part)
#context = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
#SSL connection only working on Python 3+
smtp = smtplib.SMTP(server, port)
if isTls:
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.quit()
Using python 3, you can use MIMEApplication:
import os, smtplib, traceback
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
def sendMail(sender,
subject,
recipient,
username,
password,
message=None,
xlsx_files=None):
msg = MIMEMultipart()
msg["Subject"] = subject
msg["From"] = sender
if type(recipient) == list:
msg["To"] = ", ".join(recipient)
else:
msg["To"] = recipient
message_text = MIMEText(message, 'html')
msg.attach(message_text)
if xlsx_files:
for f in xlsx_files:
attachment = open(f, 'rb')
file_name = os.path.basename(f)
part = MIMEApplication(attachment.read(), _subtype='xlsx')
part.add_header('Content-Disposition', 'attachment', filename=file_name)
msg.attach(part)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(username, password)
server.sendmail(sender, recipient, msg.as_string())
server.close()
except Exception as e:
error = traceback.format_exc()
print(error)
print(e)
Note* I simply used print(error)
in this example. Typically, I send errors to logging.critical(error)