【问题标题】:Flask: Generate preview PDF with reportlabFlask:使用reportlab生成预览PDF
【发布时间】:2017-12-05 06:54:24
【问题描述】:

我使用 Flask 发送带有 xml 和 pdf 附件的电子邮件。 在发送邮件之前,我想预览一下可用的 pdf,以便用户检查数据。

pdf 是使用 PDFOrder 函数从 xml 构造的。 PDF 存储在变量“pdf”中。那么,我的问题是如何在内存中生成 pdf 并将其作为预览提供给用户?

这是外发电子邮件的示例代码:

def send_mail():
    Email1 = session.get('Email1')
    Email2 = session.get('Email2')
    invno = session.get('invno')
    username = session['username']
    invId = session['invId']
    xmlStr,xmlFile = XmlGenerator(invId)

try:
    msg = Message(Hi,
    sender="somemail@gmail.com",
    recipients=[Email1,Email2])

    msg.body = '\nHi'

    myxmlinv = xml.dom.minidom.parseString(xmlStr)
    xmlStr = myxmlinv.toprettyxml(encoding="utf-8")
    msg.attach("Test+".xml","application/xml",xmlStr)

    buff = BytesIO()


    pdfdoc = SimpleDocTemplate(buff, pagesize = letter)

    frame = Frame(pdfdoc.leftMargin,
            pdfdoc.bottomMargin,
            pdfdoc.width,
            pdfdoc.height,
            id = 'normal')

    template = PageTemplate(id = 'test', frames = frame)

    pdfdoc.addPageTemplates(template)

    pdforder = PDFOrder(xmlStr)
    Document = pdforder.createPDF()

    pdfdoc.build(Document)

    pdf = buff.getvalue()

    buff.close()

    msg.attach("Test_"+str(invId)+".pdf", "application/pdf", str(pdf))                  
    mail.send(msg)

except Exception, e:
    return(str(e))

下面的代码将用户带到 /preview 应该打开 pdf。我希望将 pdf 存储在内存中。我将如何在 HTML 中呈现它?

<a href="/preview" target="_blank"><center><button type=button class="btn btn-default btn-lg">

谢谢!

更新 我已经设法保存了pdf。但不幸的是,它只对reportlab 进行了一些测试,虽然它有.pdf 扩展名。因此,homehow 不会呈现为 pdf。任何想法?奇怪的是,电子邮件发送与 xml 和 pdf 完美配合。你认为这部分很重要:"application/pdf", str(pdf) 这是我的更新定义

@app.route('/preview/')
def preview():
invId = session['invId']
xmlStr,xmlFile = XmlGenerator(invId)

try:
    myxmlinv = xml.dom.minidom.parseString(xmlStr)
    xmlStr = myxmlinv.toprettyxml(encoding="utf-8")

pdfdoc = SimpleDocTemplate("/var/www/FlaskApp/FlaskApp/static/mypdf.pdf", pagesize = letter)
pdforder = PDFOrder(xmlStr)
Document = pdforder.createPDF()
pdfdoc.build(Document)

except Exception, e:
    return(str(e))

return render_template("test.html")

【问题讨论】:

  • 我不确定您是否可以仅从内存中显示完整的 pdf。您可能必须先将其保存在某个地方,然后像平常一样打开它。
  • 好的,很公平。此外,可以将其保存到某个目录,没什么大不了的。
  • 是的,待命。我最近才这样做。让我抓住代码,我会把它作为答案发布
  • 也许我误读了您的评论。您是在问如何将其保存到目录中
  • 耶,应该可以解决问题。将 pdf 保存到一个目录,然后在预览页面中我会以某种方式呈现它。还必须在某个时候将其删除, os.remove 应该会有所帮助。任何其他导致预览的解决方案也可以。

标签: python html pdf flask bytesio


【解决方案1】:

据我所知,您实际上并没有命名您的 PDF 文件。这将在simpledoc 声明中完成。这是我做过的一个例子: doc = SimpleDocTemplate(filename, pagesize=letter) 在这种情况下,filename 变量是我想要 pdf 的完整路径。 例如:filename = r'C:\User\joe\Desktop\some_file.pdf'`

如果您希望文件进入您正在使用的同一目录,您可以只给它一个不带完整路径的名称。即:filename = 'some_file.pdf'

一旦您的代码点击doc.build 行,它将创建pdf。

要打开它,请使用以下行之一:

对于 MAC:

os.system("open " + filename)

窗户:

os.system("start " + filename)

【讨论】:

  • 可能我的问题描述有点弱。我实际上只是想保存生成的 pdf 并使其可供用户预览 pdf。如果这在内存中是不可能的,则可以将其保存在目录中。我还没有设法将 pdf 保存到示例代码中的目录中。
  • 是的,示例代码更多地用于选择目录。让我再看看,看看我能想出什么。我想我现在明白你想要什么了
  • pdfdoc = SimpleDocTemplate(buff, pagesize = letter) 我认为将文件命名为“buff”。我可以请您根据上面的更新发布整个代码吗?
  • 我为我的 pdf 应用扩展了这个家伙的代码。我刚刚完成构建查询数据库的应用程序将结果转换为 pdf 并将它们保存到所述目录。我还构建了一个自动运行的自动化版本,并将结果通过电子邮件发送给我的客户。这是pdf教程的链接。此代码可能需要一些修改,但效果很好。 Calazan
  • 我看到你那里有buff,但我不确定返回的是什么buff。您的系统是否正在创建任何文件?您可能需要更改 buff 中的内容
猜你喜欢
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
  • 2013-03-07
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多