Django,ReportLab PDF生成附加到电子邮件

时间:2022-05-10 00:28:24

What's the best way to use Django and ReportLab to generate PDFs and attach them to an email message?

使用Django和ReportLab生成PDF并将其附加到电子邮件消息的最佳方法是什么?

I'm using a SimpleDocTemplate and can attach the generated PDF to my HttpResponse - which is great, but I'm having trouble finding out how to exactly add that same attachment to an email:

我正在使用SimpleDocTemplate并且可以将生成的PDF附加到我的HttpResponse - 这很棒,但是我无法找到如何将相同的附件添加到电子邮件中:

    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=invoice.pdf'
    doc = SimpleDocTemplate(response, pagesize=letter)
    Document = []

... make my pdf by appending tables to the Document...

...通过将表附加到文档来制作我的pdf ...

  doc.build(Document)
  email = EmailMessage('Hello', 'Body', 'from@from.com', ['to@to.com'])
  email.attach('invoice.pdf', ???, 'application/pdf')
  email.send()

I'm just not sure how to translate my pdfdocument as a blob so that email.attach can accept it and email.send can send it.

我只是不确定如何将我的pdfdocument翻译为blob,以便email.attach可以接受它并且email.send可以发送它。

Any ideas?

有任何想法吗?

3 个解决方案

#1


6  

Using ReportLab

使用ReportLab


try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import inch

def createPDF(request):
 x=100
 y=100
 buffer=StringIO()
 p=canvas.Canvas(buffer,pagesize=letter)
 p.drawString(x,y,"HELLOWORLD")
 p.showPage()
 p.save() 
 pdf=buffer.getvalue()
 buffer.close() 
 return pdf

def someView(request):
 EmailMsg=mail.EmailMessage(YourSubject,YourEmailBodyCopy,'email@email.com',["email@email.com"],headers={'Reply-To':'email@email.com'})
 pdf=createPDF(request)
 EmailMsg.attach('yourChoosenFileName.pdf',pdf,'application/pdf')
 EmailMsg.send()

Works perfectly!!

完美的工作!

#2


3  

I don't see where your blob is rendered, so I can't advise you on how to import it. I've gotten great results using Pisa and StringIO:

我没有看到你的blob渲染的位置,所以我不能告诉你如何导入它。我使用Pisa和StringIO获得了很好的结果:

import ho.pisa as pisa
import StringIO
from django.template.loader import render_to_string
from django.core.mail import EmailMessage

render = render_to_string("books/agreement/agreement_base.html",
                              { "title": book.title,
                                "distribution": book.distribution_region })
out = StringIO.StringIO()
pdf = pisa.CreatePDF(StringIO.StringIO(render), out)
email = EmailMessage('Hello', 'Body', 'from@from.com', ['to@to.com'])
email.attach('agreement.pdf', out.getvalue(), 'application/pdf')
email.send()

That said, if your PDF exists as an independent and persistent document on your filesystem, couldn't you just:

也就是说,如果您的PDF作为文件系统上的独立且持久的文档存在,那么您不能只:

email.attach('agreement.pdf', open('agreement.pdf', 'rb').read(), 'application/pdf')

#3


3  

OK - I figured it out based on piecing a few things together -

好的 - 我根据拼凑的东西计算出来 -

First off - my requirements: - I only wanted to create the PDFs in memory - I don't want the files hanging around, as they take up space, and I don't want what might be sensitive data hanging around unprotected on the server.

首先 - 我的要求: - 我只想在内存中创建PDF - 我不希望文件闲置,因为它们占用空间,我不希望可能是敏感数据挂在服务器上不受保护的地方。

So - I picked ReportLab and Platypus functionality for generating my documents. I've invested enough time into it now, that's it's easy. So here's my approach that lets me use the DocTempates in ReportLab, allows me to use Django's email capabilities to send emails.

所以 - 我选择了ReportLab和Platypus功能来生成我的文档。我现在已投入足够的时间,这很容易。所以这是我的方法让我在ReportLab中使用DocTempates,允许我使用Django的电子邮件功能发送电子邮件。

Here's how I'm doing it:

我是这样做的:

 # Create the PDF object, using the buffer object as its "file."
  buffer = StringIO()
  doc = SimpleDocTemplate(buffer, pagesize=letter)
  Document = []

  # CRUFT PDF Data

  doc.build(Document)
  pdf = buffer.getvalue()
  buffer.close()

  email = EmailMessage('Hello', 'Body', 'from@from.com', ['to@to.com'])
  email.attach('invoicex.pdf', pdf , 'application/pdf')
  email.send()

My issue from moving from web generation to email generation was getting the right object that could be "attached" to an email. Creating a buffer, then grabbing the data off the buffer did it for me...

从Web生成转向电子邮件生成的问题是获得可以“附加”到电子邮件的正确对象。创建缓冲区,然后从缓冲区中获取数据为我做了...

#1


6  

Using ReportLab

使用ReportLab


try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import inch

def createPDF(request):
 x=100
 y=100
 buffer=StringIO()
 p=canvas.Canvas(buffer,pagesize=letter)
 p.drawString(x,y,"HELLOWORLD")
 p.showPage()
 p.save() 
 pdf=buffer.getvalue()
 buffer.close() 
 return pdf

def someView(request):
 EmailMsg=mail.EmailMessage(YourSubject,YourEmailBodyCopy,'email@email.com',["email@email.com"],headers={'Reply-To':'email@email.com'})
 pdf=createPDF(request)
 EmailMsg.attach('yourChoosenFileName.pdf',pdf,'application/pdf')
 EmailMsg.send()

Works perfectly!!

完美的工作!

#2


3  

I don't see where your blob is rendered, so I can't advise you on how to import it. I've gotten great results using Pisa and StringIO:

我没有看到你的blob渲染的位置,所以我不能告诉你如何导入它。我使用Pisa和StringIO获得了很好的结果:

import ho.pisa as pisa
import StringIO
from django.template.loader import render_to_string
from django.core.mail import EmailMessage

render = render_to_string("books/agreement/agreement_base.html",
                              { "title": book.title,
                                "distribution": book.distribution_region })
out = StringIO.StringIO()
pdf = pisa.CreatePDF(StringIO.StringIO(render), out)
email = EmailMessage('Hello', 'Body', 'from@from.com', ['to@to.com'])
email.attach('agreement.pdf', out.getvalue(), 'application/pdf')
email.send()

That said, if your PDF exists as an independent and persistent document on your filesystem, couldn't you just:

也就是说,如果您的PDF作为文件系统上的独立且持久的文档存在,那么您不能只:

email.attach('agreement.pdf', open('agreement.pdf', 'rb').read(), 'application/pdf')

#3


3  

OK - I figured it out based on piecing a few things together -

好的 - 我根据拼凑的东西计算出来 -

First off - my requirements: - I only wanted to create the PDFs in memory - I don't want the files hanging around, as they take up space, and I don't want what might be sensitive data hanging around unprotected on the server.

首先 - 我的要求: - 我只想在内存中创建PDF - 我不希望文件闲置,因为它们占用空间,我不希望可能是敏感数据挂在服务器上不受保护的地方。

So - I picked ReportLab and Platypus functionality for generating my documents. I've invested enough time into it now, that's it's easy. So here's my approach that lets me use the DocTempates in ReportLab, allows me to use Django's email capabilities to send emails.

所以 - 我选择了ReportLab和Platypus功能来生成我的文档。我现在已投入足够的时间,这很容易。所以这是我的方法让我在ReportLab中使用DocTempates,允许我使用Django的电子邮件功能发送电子邮件。

Here's how I'm doing it:

我是这样做的:

 # Create the PDF object, using the buffer object as its "file."
  buffer = StringIO()
  doc = SimpleDocTemplate(buffer, pagesize=letter)
  Document = []

  # CRUFT PDF Data

  doc.build(Document)
  pdf = buffer.getvalue()
  buffer.close()

  email = EmailMessage('Hello', 'Body', 'from@from.com', ['to@to.com'])
  email.attach('invoicex.pdf', pdf , 'application/pdf')
  email.send()

My issue from moving from web generation to email generation was getting the right object that could be "attached" to an email. Creating a buffer, then grabbing the data off the buffer did it for me...

从Web生成转向电子邮件生成的问题是获得可以“附加”到电子邮件的正确对象。创建缓冲区,然后从缓冲区中获取数据为我做了...