开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜