如何在App Engine Python中将使用Reportlab生成的PDF附加到电子邮件?

3

我有一个使用Reportlab库生成PDF文件的方法:

def obtenerPDFNuevoPedido(self, handler,rsUsuarioPedido, rsPedido):
    handler.response.headers['Content-Type'] = 'application/pdf'
    handler.response.headers['Content-Disposition'] = 'attachment; filename=output.pdf'
    story = []
    story.append(Paragraph('CHIPAS', ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=20)))
    story.append(Paragraph('____________ENLANUBE', ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=20)))
    story.append(Spacer(6, 22))
    story.append(Table([[Paragraph(str(strftime("%Y-%m-%d", gmtime())), ParagraphStyle(name="centeredStyle", alignment=TA_LEFT, fontSize=7)), 
    Paragraph(str(strftime("%H:%M:%S", gmtime())), ParagraphStyle(name="centeredStyle", alignment=TA_RIGHT, fontSize=7))]],colWidths=[5.05 * cm, 3.1 * cm]))
    story.append(Paragraph("DEVELOPED AT ROSHKA-LABS", ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=6)))
    story.append(Paragraph('-'*50, styleCentered))
    #...
    #...
    doc = SimpleDocTemplate(handler.response.out, pagesize=letter)
    doc.build(story) 

当我调用那个方法时,它会打开一个保存对话框,让我可以指定文件应该保存在哪里。
我应该怎么做才能将生成的 PDF 附加到电子邮件中?
我看过这个例子:
from google.appengine.api import urlfetch
from google.appengine.api import mail  

url = "http://www.abc.com/files/file.pdf" 
result = urlfetch.fetch(url)

if result.status_code == 200: 
  document = result.content

mail.send_mail(sender="youremail@yourdomain.com",
               to="receiver@hisdomain.com",
               subject="The file you wanted",
               body="Here is the file you wanted",
               attachments=[("The file name.pdf", document)])

但是我不知道如何在这种特定情况下应用它。

提前感谢!

解决方案:

根据@Jesús的建议,这是我解决问题的方法:

class PdfTable(db.Model):
    fecha = db.DateTimeProperty(auto_now_add=True)
    archivoBlob = db.BlobProperty()

def obtenerPDFNuevoPedido(self, handler,rsUsuarioPedido, rsPedido):
#1)I generated the PDF this way:
        styleCentered = ParagraphStyle(name="centeredStyle", alignment=TA_CENTER)
        styleCenteredLeft = ParagraphStyle(name="centeredStyle", alignment=TA_LEFT)
        styleCenteredRight = ParagraphStyle(name="centeredStyle", alignment=TA_RIGHT)

        story = []
        story.append(Paragraph('CHIPAS', ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=20)))
        story.append(Paragraph('____________ENLANUBE', ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=20)))
        story.append(Spacer(6, 22))
        story.append(Table([[Paragraph(str(strftime("%Y-%m-%d", gmtime())), ParagraphStyle(name="centeredStyle", alignment=TA_LEFT, fontSize=7)), Paragraph(str(strftime("%H:%M:%S", gmtime())), ParagraphStyle(name="centeredStyle", alignment=TA_RIGHT, fontSize=7))]],colWidths=[5.05 * cm, 3.1 * cm]))
        story.append(Paragraph("DEVELOPED AT ROSHKA-LABS", ParagraphStyle(name="centeredStyle", alignment=TA_CENTER, fontSize=6)))
        story.append(Paragraph('-'*50, styleCentered))
        data = [[Paragraph("Usuario",ParagraphStyle(name="centeredStyle", alignment=TA_LEFT, fontSize=7)), Paragraph("Producto/Precio/Cantidad",ParagraphStyle(name="centeredStyle", alignment=TA_LEFT, fontSize=7)),Paragraph("Total", ParagraphStyle(name="centeredStyle", alignment=TA_RIGHT, fontSize=7))]]
        #
        #
        #
#2)Inside the same method, I saved the PDF file in the Datastore       
        pdf = StringIO.StringIO()

        doc = SimpleDocTemplate(pdf, pagesize=letter)
        doc.build(story)

        content = pdf.getvalue()

        blob = model.PdfTable()
        blob.archivoBlob = db.Blob(content)
        blob.put()
#3)The file recently stored  in the datastore was attached like this:        
        mail.send_mail(sender="youremail@yourdomain.com",
               to="receiver@hisdomain.com",
               subject="The file you wanted",
               body="Here is the file you wanted",
               attachments=[('resumen_pedido.pdf'), blob.archivoBlob)])

虽然我不知道这是否是解决问题的更有效的方法...但它确实起作用了

2个回答

4
不需要向Blobstore写入。只需使用文件类型cStringIO存储您的pdf内容,然后用.get_value()输出值即可。
self.result = cStringIO.StringIO() 
self.pdf = pisa.pisaDocument(cStringIO.StringIO(self.html.encode("UTF-8")), self.result,encoding='UTF-8')
mail.send_mail,sender_address, to_address, subject, body,attachments=[(file_name,self.result.get_value())]

谢谢,这对我有用。不过你在 StringIO.getvalue() 方法中打错了一个字。 - alecdotico

2

我认为正确的做法是:

  • 生成PDF文件(第一段代码)
  • 将PDF文件保存在数据存储中。
  • 使用第二段代码将PDF附加到电子邮件中。

试试看,然后告诉我们结果 =)


谢谢你的回答,Jesus。我需要先调查如何将生成的PDF保存到数据存储中。你有任何想法吗? - Lucas
将其保存为Blob类型并存储在数据存储中:http://code.google.com/intl/zh-CN/appengine/docs/python/datastore/typesandpropertyclasses.html#Blob - Jesús

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接