简体   繁体   中英

attach excel file to email using python

I am trying to send an excel file via email but somehow the format and text is altered. I am using python3 and MIMEMultipart().

message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject
message.attach(MIMEText(body, "plain"))

filename = "file_name.xlsx"  # In same directory as script
# Open PDF file in binary mode
with open(filename, 'r') as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

encoders.encode_base64(part)
message.attach(part)
text = message.as_string()

# Log in to server using secure context and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL(smtp_server, 465 , context=context) as server:
    server.login(sender_email, password)
    server.sendmail(sender_email, receiver_email, text)

The comment is wrong; you are not opening the file in binary mode ( 'rb' ) and so you are basically corrupting it

Following up on my answer to your previous question , here is a refactored version of your code to use the modern, Python 3.6+ EmailMessage library instead.

from email.message import EmailMessage

... 
message = EmailMessage()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject
message.set_content(body, 'plain')

# The OS will look in the current working directory, not in the directory where you saved the script
filename = "file_name.xlsx"
# Notice 'rb'
with open(filename, 'rb') as attachment:
    message.add_attachment(
        attachment.read(),
        maintype='application', subtype='octet-stream')

# AGAIN, no need for a context if you are just using the default SSL
with smtplib.SMTP_SSL(smtp_server, 465) as server:
    server.login(sender_email, password)
    # AGAIN, prefer the modern send_message method
    server.send_message(message)

As you notice, there's quite a lot less boilerplate than with the older Email.Message API from Python 3.5 or earlier.

A common arrangement is to have a multipart/related message with body text and an attachment, but the body text represented as a multipart/alternative structure with both a text/plain and a text/html rendering of the message. If you want this, the "asparagus" example from the email module documentation's examples page contains a recipe which demonstrates that (though it also includes an image instead of a binary attachment, and displays it inline in the HTML attachment).

Tangentially, you might be better off choosing a less clunky format than Excel for sharing data. If it's just a table, a CSV text file would be a lot smaller as well as easier to process on the receiving end. (If you do send Excel, probably actually use its designated MIME type rather than the generic application/octet-stream .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM