how to send email with Excel file (xlsx)attachment in Python - python

I need to send a email with Excel attachment。
my code is like below , it is ok to send the email ,
but when I received the email, the attachment file is not Excel files~~
it seems that the wrong format I have attached~~~
I have add different email address to receive this email,
but they were all received the unknown format files
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import datetime
import sys
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from email.mime.base import MIMEBase
from email import encoders
mail_host = "mysever" # 设置服务器
mail_user = "me" # 用户名
mail_pass = "me123" # 口令
EMAILHOME = u'F:\Workfiles\weekreport\\forupdate'
sender = 'me#gmail.com'
receivers = ['aaaaaa#qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
def getReceiverlist(filename):
lif = open(filename)
li = lif.readlines()
lif.close()
for x in range(len(li)):
li[x] = li[x].strip(os.linesep)
while '' in li:
li.remove('')
return li
def aisendmail():
ret = True
try:
message = MIMEMultipart()
message['From'] = Header("myname", 'utf-8')
message['To'] = Header("youname", 'utf-8')
message.attach(MIMEText('weekreport', 'plain', 'utf-8')) # 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
subject = 'myname-weekreport'
message['Subject'] = Header(subject, 'utf-8')
att1 = MIMEBase('application', "octet-stream")
att1.set_payload(open(u"F:\Workfiles\weekreport\\forupdate\myname_weekreport_20170821.xlsx",'rb').read())
encoders.encode_base64(att1)
att1.add_header('Content-Disposition', 'attachment; filename="myname-weekreport"')
message.attach(att1)
if os.path.exists(EMAILHOME + r'\receivers.txt'):
receiverslist = getReceiverlist(EMAILHOME + r'\receivers.txt')
print("receicerlist include:", receiverslist)
if len(receiverslist) == 0:
print"no receiver!!!"
receiverslist = receivers
else:
receiverslist = receivers
server = smtplib.SMTP()
server.connect(mail_host, 25) # 发件人邮箱中的SMTP服务器,端口是25
server.login(mail_user, mail_pass) # 括号中对应的是发件人邮箱账号、邮箱密码
server.sendmail(sender, receiverslist, message.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
server.quit() # 关闭连接
except smtplib.SMTPException: # 如果 try 中的语句没有执行,则会执行下面的 ret=False
ret = False
return ret
result = aisendmail()
if result:
print "邮件发送成功"
else:
print "Error: 无法发送邮件"
I follow different ways to add excel attachment as below: but they were all failed(it means it could not receive excel format file)
Method 1:
att1 = MIMEBase('application', 'octet-stream') #'octet-stream': binary data
att1.set_payload(open(file, 'rb').read())
encoders.encode_base64(att1)
att1.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
msg.attach(att1)
Result:
received a unknown format file
Method 2:
with open(u"F:\Workfiles\周报\\forupdate\xxx_周报_20170821.xlsx", "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(u"F:\Workfiles\周报\\forupdate\xxx_周报_20170821.xlsx")
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(u"F:\Workfiles\周报\\forupdate\xxx_周报_20170821.xlsx")
message.attach(part)
Result:
received a bin format file
Method 3:
att1 = MIMEApplication(open('foo.xlsx','rb').read())
att1.add_header('Content-Disposition', 'attachment', filename="foo.xlsx")
msg.attach(att1)
Result:
receive a unknown format file

Try this code to add the attachment:
with open(f, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)

I was trying to send a body formatted in HTML, and add an excel file as an attachment - this took me ages to figure out, so best thought I should share my solution!
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'This is my subject line'
msg['To'] = xxxxx#xmail.com
msg['From'] = yyyyy#ymail.com
msg.add_alternative(f"""\
<!DOCTYPE html>
<html>
<body>
<h3>This is my message!</h3>
</body>
</html>""",
subtype='html')
with open('MyExcelFile.xlsx', 'rb') as fh:
attachment = fh.read()
msg.add_related(attachment, maintype='application', subtype='xlsx', filename='MyExcelFile.xlsx')
with smtplib.SMTP_SSL(host='smtp.gmail.com', port=465) as smtp:
smtp.login('obviouslyfake#gmail.com', 'WhoDoYouThinkIAm')
smtp.send_message(msg)

Related

How to use python to send emails with multiple attachments

I can't get this to attach multiple documents to an email. It attaches the first document and then sends the document. I am a noob when it comes to using the auto-email function. Could anyone explain this or show me how to fix this?
self.name = name
fromaddr = "Your Email"
toaddr = "Sending Email"
msg = MIMEMultipart()
#email address
msg['From'] = fromaddr
# Receivers email address
msg['To'] = toaddr
#subject
msg['Subject'] = ' Weekly Report'
#body of the mail
body = 'Hey, I\'m testing the automated email function, let me know if you get it and how does it look!'
#msg instance
msg.attach(MIMEText(body, 'plain'))
# open the file to be sent
a = 0
for i in self.name:
while a < len(self.name):
filename = i + '.pdf'
attachment = open(i + '.pdf', "rb")
a+=1
print(len(self.name))
print(a)
p = MIMEBase('application', 'octet-stream')
p.set_payload((attachment).read())
encoders.encode_base64(p)
p.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(p)
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
s.login(fromaddr, "password")
text = msg.as_string()
s.sendmail(fromaddr, toaddr, text)
s.quit()
Try this (Reference:- https://dzone.com/articles/send-email-attachments-python)
import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
def send_mail(send_from, send_to, subject, text, files=[], server="localhost"):
assert type(send_to)==list
assert type(files)==list
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach( MIMEText(text) )
for f in files:
part = MIMEBase('application', "octet-stream")
part.set_payload( open(file,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
msg.attach(part)
smtp = smtplib.SMTP(server)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()

Send email through AWS Workmail from Python script

Is it possible to send automated email messages with Amazon Workmail through a Python script?
My code keeps hanging and when I can the run I get a SMTP server connection error. How can I fix this? I presume, its the SMTP configuration, but does anyone know what that is?
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os.path
import csv
from random import randint
from time import sleep
def send_email(email_recipient,
email_subject,
email_message,
attachment_location=''):
email_mime_sender = 'xxxxx <xxxxx#yyyyyy.co.uk>'
email_sender = 'xxxxx'
email_password = 'xxxxx'
msg = MIMEMultipart()
msg['From'] = email_mime_sender
msg['To'] = email_recipient
msg['Subject'] = email_subject
msg.attach(MIMEText(email_message, 'plain'))
if attachment_location != '':
filename = os.path.basename(attachment_location)
attachment = open(attachment_location, "rb")
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',
"attachment; filename= %s" % filename)
msg.attach(part)
try:
server = smtplib.SMTP_SSL('smtp.mail.eu-west-1.awsapps.com', 465)
server.ehlo()
server.starttls()
server.login(email_sender, email_password)
text = msg.as_string()
server.sendmail(email_sender, email_recipient, text)
print('Email sent to %s' % email_recipient)
server.quit()
except:
print("SMTP server connection error")
return True
def main():
file = 'test.csv'
with open(file, "rb") as f:
next(f)
for line in f:
line = line.replace("\n", "")
line = line.replace("\r", "")
split_line = line.split(",")
email_subject = 'Can I ask you a few questions?'
raw_email_message = [
'Test',
'Test'
]
email_message = '\n\n'.join(raw_email_message)
send_email(split_line[1], email_subject, email_message, '')
sleep(randint(1, 3))
main()
Removing server.starttls() from the this block fixed it:
try:
server = smtplib.SMTP_SSL('smtp.mail.eu-west-1.awsapps.com', 465)
server.ehlo()
server.login(email_user, email_password)
text = msg.as_string()
server.sendmail(email_sender, email_recipient, text)
print('Email sent to %s' % email_recipient)
server.quit()
except Exception as e:
print(e)
print("SMTP server connection error")
return True

Emailing with an attachment with Python

import smtplib
import mechanize
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def sem():
if not os.path.isfile('key.txt'):
print('below details are req to send report')
gmail_user = input('enter your email=')
gmail_app_password = input('enter your email password=')
print('pls accept the login in your gmail account ')
ke = open('key.txt',mode="w+")
ke.write(gmail_user)
ke.write(':')
ke.write(gmail_app_password)
ke.close()
if not os.path.isfile('sto.txt'):
gmai = input('enter the email to send report=')
ke = open('sto.txt',mode="w+")
ke.write(gmai)
ke.close()
with open('key.txt',mode="r")as f:
ds=f.readlines()
d=''.join(ds)
r=d.split(':')
with open('sto.txt',mode="r")as f:
ds=f.readlines()
f=ds
print(f)
gmail_user = r[0]
gmail_app_password = r[1]
sent_from = gmail_user
sent_to = ds
sent_subject = "hey amo lio ,how are ?"
sent_body = ("Hey, what's up? friend!")
email_text = """\
To: %s
Subject: %s
%s
""" % (", ".join(sent_to), sent_subject, sent_body)
mail = MIMEMultipart()
mail["Subject"] = sent_subject
mail["From"] = sent_from
mail["To"] = sent_to
mail.attach[MIMEText(sent_body,'html')]
ctype, encoding = mimetypes.guess_type(_file)
maintype, subtype = ctype.split('/', 1)
fp = open("./data/mood.txt")
msg = MIMEText(fp.read(), _subtype=subtype)
fp.close()
filename = os.path.basename(_file)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
mail.attach(msg)
print('done')
server.sendmail(sent_from, sent_to, mail.as_string())
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_app_password)
server.sendmail(sent_from, sent_to, email_text)
server.close()
print('Email sent!')
except Exception as exception:
print("Error: %s!\n\n" % exception)
sem()
How can I attach the helloword.txt file in this email? This code is working fine, I just want to send an attachment along with it. This code lets me me send the body without any attachment. Also, how do I encrypt the key.txt file which store email address and password, and to send email it it requires the password to be entered (diff pass)?
You need to use the 'MIMEMultipart' module to attach files.
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
mail = MIMEMultipart()
mail["Subject"] = sent_subject
mail["From"] = sent_from
mail["To"] = sent_to
mail.attach(MIMEText(sent_body,'html'))
ctype, encoding = mimetypes.guess_type(_file)
maintype, subtype = ctype.split('/', 1)
fp = open("/path/to/attachment/file.txt")
# If file mimetype is video/audio use respective email.mime module.
# Here assuming 'maintype' == 'text' we will use MIMEText
msg = MIMEText(fp.read(), _subtype=subtype)
fp.close()
filename = os.path.basename(_file)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
mail.attach(msg)
server.sendmail(sent_from, sent_to, mail.as_string())
import smtplib
import mechanize
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
import pdb
def email:
sender_address = gmail_user
#make it input
receiver_address = gmail_user
#Setup the MIME
fromaddr = gmail_user
sendto = gmail_app_password
sender_pass = gmail_app_password = input('enter your email password')
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = sendto
msg['Subject'] = 'This is cool'
body = "this is the body of the text message"
msg.attach(MIMEText(body, 'plain'))
filename = 'mood.txt'
attachment = open('./data/mood.txt', 'rb')
part = MIMEBase('application', "octet-stream")
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename= %s' % filename)
msg.attach(part)
smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(gmail_user, gmail_app_password)
text = msg.as_string()
smtpObj.sendmail(fromaddr, sendto , text)
smtpObj.quit() # attach the instance 'p' to instance 'msg'
here is perfect working code for sending email

How to change actual location to temporary, add headers and remove space in csv file on Python Email table from MySQL?

I have a python code that run a MySQL query and send a email with csv attachment. I need to make following three changes. Can anybody please help me with this?
I need to change the actual location to a temporary location (I tired, it gaves me an error then I chnage it to the real location)
I have no headers on my result csv file. How do I add header on result csv?
It puts a empty raw between each raw, how do I remove that too.
Code -
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
import mysql.connector
import csv
my_db = mysql.connector.connect(
host="localhost",
user="root",
passwd="admin",
database="simplymacstaging"
)
my_cursor = my_db.cursor()
my_cursor.execute("SELECT CONVERT(DateCreated, Date) 'Date', StoreName, ROUND(sum(TotalCost), 2) 'TotalCost' "
"FROM simplymacstaging.ajdustmenthistory WHERE ReasonCode = 'Negligence - Service' AND "
"CONVERT(DateCreated, Date) >= '2019-02-03' GROUP by StoreName, Date")
databases = my_cursor.fetchall()
fp = open('C:\#Emailproject/emailtest.csv', 'w')
attach_file = csv.writer(fp)
attach_file.writerows(databases)
fp.close()
# My email
fromaddr = "******************#gmail.com"
# EMAIL ADDRESS YOU SEND TO
toaddr = "**********#gmail.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Test Email Data" # SUBJECT OF THE EMAIL
body = "Hello, Please see the attched report for week. Thank you, ****"
msg.attach(MIMEText(body, 'plain'))
filename = "Test Email.csv" # NAME OF THE FILE WITH ITS EXTENSION
attachment = open("C:\#Emailproject/emailtest.csv", "rb") # PATH OF THE FILE
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(part)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "***********") # YOUR PASSWORD
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
sample result image -
Thank you so much
to avoid the empty rows try this
fp = open('C:\#Emailproject/emailtest.csv', 'w', newline='')
to add the header row
attach_file.writerow(["date", "address", "col3"])
attach_file.writerows(databases)

Sending single email with 3 different attachments python 3

I'm just looking to send an email with 3 csv file attachments. When i get it to run, trying a solution i found on here, it gives me a BIN file instead of the 3 files. Or, trying another solution, it will only send the last of the the 3 files. When i run the code below, its gives me TypeError: add.header() takes 3 positional arguments but 4 were given.
I understand that it can be done with a function, but i'm not sure how to have it pull all three files into it. I've spent numerous hours trying to figure it out.
Posting it on here is my last resort. I appreciate any help in finding a solution.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import time
import os
msg = MIMEMultipart()
msg['From'] = EMAIL_FROM
msg['To'] = ", ".join(RECIPIENT_LIST)
msg['Subject'] = 'Louisiana Contractors List'
#email content
message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>
Let me know if you have any questions
</body>
</html>
"""
msg.attach(MIMEText(message, 'html'))
files = [
'C:/Users/rkrouse/Downloads/search-results.csv',
'C:/Users/rkrouse/Downloads/search-results(1).csv',
'C:/Users/rkrouse/Downloads/search-results(2).csv']
for a_file in files:
attachment = open(a_file, 'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results.csv'))
encoders.encode_base64(part)
msg.attach(part)
for a_file in files:
attachment = open(a_file, 'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results(1).csv'))
encoders.encode_base64(part)
msg.attach(part)
for a_file in files:
attachment = open(a_file, 'rb')
part = MIMEBase('application','octet-stream')
part.set_payload(attachment.read())
part.add_header('Content-Disposition', 'attachment', a_file = os.path.basename('C:/Users/rkrouse/Downloads/search-results(2).csv'))
encoders.encode_base64(part)
msg.attach(part)
#sends email
smtpserver = smtplib.SMTP(EMAIL_SERVER, EMAIL_PORT)
smtpserver.sendmail(EMAIL_FROM, RECIPIENT_LIST, msg.as_string())
smtpserver.quit()
Updated tested solution:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import time
import os
msg = MIMEMultipart()
msg['From'] = EMAIL_FROM
msg['To'] = ", ".join(RECIPIENT_LIST)
msg['Subject'] = 'Louisiana Contractors List'
#email content
message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>
Let me know if you have any questions
</body>
</html>
"""
msg.attach(MIMEText(message, 'html'))
files = [
'C:/Users/rkrouse/Downloads/search-results.csv',
'C:/Users/rkrouse/Downloads/search-results(1).csv',
'C:/Users/rkrouse/Downloads/search-results(2).csv']
for a_file in files:
attachment = open(a_file, 'rb')
file_name = os.path.basename(a_file)
part = MIMEBase('application','octet-stream')
part.set_payload(attachment.read())
part.add_header('Content-Disposition',
'attachment',
filename=file_name)
encoders.encode_base64(part)
msg.attach(part)
#sends email
smtpserver = smtplib.SMTP(EMAIL_SERVER, EMAIL_PORT)
smtpserver.sendmail(EMAIL_FROM, RECIPIENT_LIST, msg.as_string())
smtpserver.quit()
As you can see you need to specify the filename in the base64 encoding.
Also you are iterating the files three time.
A for loop is used to go through a list, set, array, etc. One for loop (as all attachments are in one list) should be enough.
Following is the simple snippet that I used to send an email to multiple people with multiple file attachments.
# -*- coding: utf-8 -*-
import smtplib
import mimetypes
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
import ntpath
sender_address = 'vijay.anand#xxxx.com'
default_subject = 'Test email from {}'.format(sender_address)
smtp_server_address = '10.111.41.25'
smtp_port_number = 25
default_message = message = """<html>
<body>
Attached is the Louisiana Contractors Spreadsheet.
<br><br>
Let me know if you have any questions
</body>
</html>
"""
def send_by_smtp(to=None, cc=None, bcc=None, subject=None, attachments=None, attachment_type='plain'):
"""
Snippet to send an email to multiple people along with multiple attachments.
:param to: list of emails
:param cc: list of emails
:param bcc: list of emails
:param subject: Email Subject
:param attachments: list of file paths
:param attachment_type: 'plain' or 'html'
:return: None
"""
email_from = sender_address
email_to = list()
files_to_send = attachments
msg = MIMEMultipart()
msg["From"] = email_from
if to:
to = list(set(to))
email_to += to
msg["To"] = ', '.join(to)
if cc:
cc = list(set(cc))
email_to += cc
msg["Cc"] = ', '.join(cc)
if bcc:
bcc = list(set(bcc))
email_to += bcc
msg["Bcc"] = ', '.join(bcc)
if subject:
msg["Subject"] = subject
msg.preamble = subject
else:
msg["Subject"] = default_subject
msg.preamble = default_subject
body = default_message
msg.attach(MIMEText(body, attachment_type))
if files_to_send:
for file_to_send in files_to_send:
content_type, encoding = mimetypes.guess_type(file_to_send)
if content_type is None or encoding is not None:
content_type = "application/octet-stream"
maintype, subtype = content_type.split("/", 1)
if maintype == "text":
with open(file_to_send) as fp:
# Note: we should handle calculating the charset
attachment = MIMEText(fp.read(), _subtype=subtype)
elif maintype == "image":
with open(file_to_send, "rb") as fp:
attachment = MIMEImage(fp.read(), _subtype=subtype)
elif maintype == "audio":
with open(file_to_send, "rb")as fp:
attachment = MIMEAudio(fp.read(), _subtype=subtype)
else:
with open(file_to_send, "rb") as fp:
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment", filename=ntpath.basename(file_to_send))
msg.attach(attachment)
try:
smtp_obj = smtplib.SMTP(host=smtp_server_address, port=smtp_port_number, timeout=300)
smtp_obj.sendmail(from_addr=email_from, to_addrs=list(set([email_from] + email_to)), msg=msg.as_string())
print("Successfully sent email to {}".format(str(email_to)))
smtp_obj.quit()
return True
except smtplib.SMTPException:
print("Error: unable to send email")
return False
if __name__ == '__main__':
print('Send an email using Python')
result = send_by_smtp(to=['vijay#xxxx.com', 'tha#xxx.com'],
cc=['anandp#xxxx.com', 'nitha#xxxx.com'],
bcc=['vij#xxxx.com', 'Sun#xxxx.com'],
subject='Louisiana Contractors List',
attachments=['test.txt', '1.JPG', '2.PNG', '3.PNG', '4.PNG'],
attachment_type='html')
if result:
print('Email Sent Successfully')
else:
print('Email Sending Failed')

Categories

Resources