Dynamically generate PDF and email it using django
I have a django app that dynamically generates a PDF (using reportlab + pypdf) from user input on an HTML form, and returns the HTTP response with an application/pdf
MIMEType.
I want to have the option between doing the above, or emailing the generated pdf, but I cannot figure out how to use the Email开发者_StackOverflow社区Message class's attach(filename=None, content=None, mimetype=None)
method. The documentation doesn't give much of a description of what kind of object content
is supposed to be. I've tried a file object and the above application/pdf
HTTP response.
I currently have a workaround where my view saves a pdf to disk, and then I attach the resulting file to an outgoing email using the attach_file()
method. This seems wrong to me, and I'm pretty sure there is a better way.
Ok I've figured it out.
The second argument in attach()
expects a string. I just used a file object's read()
method to generate what it was looking for:
from django.core.mail import EmailMessage
message = EmailMessage('Hello', 'Body goes here', 'from@example.com',
['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
headers = {'Reply-To': 'another@example.com'})
attachment = open('myfile.pdf', 'rb')
message.attach('myfile.pdf',attachment.read(),'application/pdf')
I ended up using a tempfile instead, but the concept is the same as an ordinary file object.
Generate the file temp.
from django.utils import timezone
from io import BytesIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
def generate_pdf(pk):
y = 700
buffer = BytesIO()
p = canvas.Canvas(buffer, pagesize=letter)
p.setFont('Helvetica', 10)
p.drawString(220, y, "PDF generate at "+timezone.now().strftime('%Y-%b-%d'))
p.showPage()
p.save()
pdf = buffer.getvalue()
buffer.close()
return pdf
Attach the PDF to message
from django.core.mail import EmailMessage
def send(request)
pdf = generate_pdf(pk)
msg = EmailMessage("title", "content", to=["email@gmail.com"])
msg.attach('my_pdf.pdf', pdf, 'application/pdf')
msg.content_subtype = "html"
msg.send()
Based on the example in your link:
message.attach('design.png', img_data, 'image/png')
Wouldn't your content for a pdf just be the same output that you would normally write to the pdf file? Instead of saving the generated_pdf_data to myfile.pdf, plug it into the content field of the message.attach:
message.attach('myfile.pdf', generated_pdf_data, 'application/pdf')
I found this to work
message.attach('myfile.pdf', pdf.getvalue() , 'application/pdf')
When using
message.attach('myfile.pdf', pdf.read() , 'application/pdf')
The pdf cannot be opened as it's corrupt
精彩评论