发送python电子邮件时添加excel文件附件
Posted
技术标签:
【中文标题】发送python电子邮件时添加excel文件附件【英文标题】:add excel file attachment when sending python email 【发布时间】:2014-10-10 08:16:53 【问题描述】:如何在使用 python 发送电子邮件时添加文档附件? 我收到要发送的电子邮件 (请忽略:我正在循环发送电子邮件以每 5 秒发送一次,仅用于测试目的,我希望它每 30 分钟发送一次,只需将 5 更改为 1800)
到目前为止,这是我的代码。如何从我的计算机附加文档?
#!/usr/bin/python
import time
import smtplib
while True:
TO = 'xxxx@gmail.com'
SUBJECT = 'Python Email'
TEXT = 'Here is the message'
gmail_sender = 'xxxx@gmail.com'
gmail_passwd = 'xxxx'
server = smtplib.SMTP('smtp.gmail.com',587)
server.ehlo()
server.starttls()
server.ehlo()
server.login(gmail_sender, gmail_passwd)
BODY = '\n'.join([
'To: %s' % TO,
'From: %s' % gmail_sender,
'Subject:%s' % SUBJECT,
'',
TEXT
])
try:
server.sendmail(gmail_sender,[TO], BODY)
print 'email sent'
except:
print 'error sending mail'
time.sleep(5)
server.quit()
【问题讨论】:
【参考方案1】:要发送附件,请创建一个 MIMEMultipart 对象并将附件添加到该对象。这是来自 python email examples 的示例。
# Import smtplib for the actual sending function
import smtplib
# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
COMMASPACE = ', '
# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = COMMASPACE.join(family)
msg.preamble = 'Our family reunion'
# Assume we know that the image files are all in PNG format
for file in pngfiles:
# Open the files in binary mode. Let the MIMEImage class automatically
# guess the specific image type.
fp = open(file, 'rb')
img = MIMEImage(fp.read())
fp.close()
msg.attach(img)
# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())
s.quit()
【讨论】:
我的文件也是excel文件 Here 是另一个堆栈溢出答案,它显示了如何将任何文件编码为 mime 附件。【参考方案2】:这是对我有用的代码——在 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()
【讨论】:
它工作得很好,但试图通过这一行中的变量发送文件名:part.add_header('Content-Disposition', 'attachment; filename="WorkBook3.xlsx"')
我想从参数列表中添加文件,然后是文件名本身,例如part.add_header('Content-Disposition', 'attachment; filename=files')
【参考方案3】:
这里只是对上面 SoccerPlayer 帖子的一个小调整,它让我完成了 99% 的任务。我找到了一个 sn-p Here,它让我走完了剩下的路。没有功劳归于我。只是发布以防万一它有助于下一个人。
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()
【讨论】:
这更容易理解并且对我有用,谢谢【参考方案4】:我找到了一种简单的方法,使用 Corey Shafer 在this video 中关于使用 python 发送电子邮件的解释。
import smtplib
from email.message import EmailMessage
SENDER_EMAIL = "sender_email@gmail.com"
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)
【讨论】:
关于xlsx
,正确的子类型应该是vnd.openxmlformats-officedocument.spreadsheetml.sheet
proof【参考方案5】:
使用python 3,可以使用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)
注意*我在这个例子中只使用了print(error)
。通常,我将错误发送到logging.critical(error)
【讨论】:
以上是关于发送python电子邮件时添加excel文件附件的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Python 数据帧存储在内存中并将其作为 excel 附件发送到特定的电子邮件地址?
如何用ABAP代码实现上传本地excel文件,并将其作为附件发邮件