【问题标题】:Flask handling a PDF as its own pageFlask 将 PDF 作为自己的页面处理
【发布时间】:2013-08-19 08:08:36
【问题描述】:

对于我的个人网站,我想为我的简历创建一个单独的页面,即 PDF。我尝试了多种方法,但我不知道如何让烧瓶处理 PDF。

【问题讨论】:

  • 你能让网络服务器静态地提供文件吗(就像你可能正在为你的/static 文件做的那样)。如果是这样,你可以在你的 Flask 应用程序中创建一个指向静态文件的链接吗?

标签: python pdf web flask


【解决方案1】:

您可以在 5 行中使用flask send_filesend_static_file 函数:

from flask import send_file, current_app as app

@app.route('/show/static-pdf/')
def show_static_pdf():
    with open('/path/of/file.pdf', 'rb') as static_file:
        return send_file(static_file, attachment_filename='file.pdf')

This snippet link 很有帮助

如果你想从某个目录发送文件,也可以使用send_from_directory

from flask import send_from_directory, current_app as app

@app.route('/show/PDFs/')
def send_pdf():
    return send_from_directory(app.config['UPLOAD_FOLDER'], 'file.pdf')

read more 关于send_from_directory

【讨论】:

  • 最好使用with打开文件,这样可以确保文件在使用后关闭。
  • 好的,谢谢@Audrius-Kažukauskas
  • 我知道这是几年后的事了,但我的代码是 server_bp.route('/resume') def resume(): return send_file('static/pdf/resume.pdf', attachment_filename='resume.pdf') 工作正常。我发现这个答案最有帮助,但我不确定with open 是你想要的。他们的浏览器将显示 pdf。您不希望您的服务器打开文件。
  • 嗨@DavidFrick,在许多情况下,我们在发送给客户端之前制作文件内容,并且在某些情况下,我们不会将内容存储在真实文件中,而是使用缓冲区或类似 BytesIO 的东西
  • @M.javid 那说得通!旁注:可以这么说,您知道将 pdf 显示为页面中的容器的任何方式吗?这个解决方案,至少对我来说,让浏览器下载 pdf 并作为新页面打开,失去在我的网站上导航的能力。
【解决方案2】:

我知道已经很晚了,但我只是找到了最简单的方法,而且不在其中。

只需重定向到文件的路径作为静态文件,带有任何超链接:

"/docs/sample.pdf" #the browser will take care about showing it

或者,如果您想要一种更清洁的方式...我刚刚为 pdf 制作了一个烧瓶页面,如下所示:

@app.route('/pdf/') #the url you'll send the user to when he wants the pdf
def pdfviewer():
    return redirect("/docs/sample.pdf") #the pdf itself

...我想这有点像给 pdf 链接 (?) 提供一个变量名,如果我需要根据变量将用户发送到不同的 pdf,也应该更容易适应。

我在想这几行:

@app.route('/pdf<number>') #passing variable through the url
def pdfviewer(number):
    if number == 1: #pdf depending on that variable
        return redirect("/docs/sample1.pdf")
    elif number == 2:
        return redirect("/docs/sample1.pdf")
    ...
    else:
        return "Hey I don't have such pdf" #basic html page as default

顺便说一句:我正在研究 pythonAnywhere,所以我必须首先在 Web 选项卡中定义 static files 的路径,这样我才能向用户显示静态文件。

【讨论】:

【解决方案3】:

如果你尝试做你的典型

<a href="path/doc.pdf">My Resume</a> 

用户单击链接并下载 pdf 的位置,您需要将文档放在静态文件夹中。

然后你会得到类似的结果:

<a href="../static/doc.pdf">My Resume</a>

【讨论】:

    【解决方案4】:

    给任何遇到此问题的人的说明,因为他们正在尝试使用 Flask 从数据库中提供 PDF 文件。当文件存储在数据库中时嵌入 PDF 并不像在静态文件夹中那样简单。您必须使用make_response 函数并为其提供适当的标题,以便浏览器知道如何处理您的二进制 PDF 数据,而不是像往常一样从视图函数中返回它。这里有一些伪代码可以提供帮助:

    from flask import make_response
    
    @app.route('/docs/<id>')
    def get_pdf(id=None):
        if id is not None:
            binary_pdf = get_binary_pdf_data_from_database(id=id)
            response = make_response(binary_pdf)
            response.headers['Content-Type'] = 'application/pdf'
            response.headers['Content-Disposition'] = \
                'inline; filename=%s.pdf' % 'yourfilename'
            return response
    

    如果您希望文件下载而不是显示在浏览器中,您可以将 Content-Disposition 从“内联”更改为“附件”。您也可以将此视图放在子域中,例如docs.yourapp.com 而不是 yourapp.com/docs。最后一步是将该文档实际嵌入到浏览器中。在您喜欢的任何页面上,只需使用 rawrgulmuffin 的策略:

    <embed src="/docs/pdfid8676etc" width="500" height="375">
    

    您甚至可以使用 Jinja2 模板使 src 动态化。让我们把它放在 doc.html 中(注意大括号):

    <embed src="/docs/{{doc_id}}">
    

    然后在视图函数中,您只需返回带有适当 doc_id 的渲染模板:

    from flask import render_template
    
    @app.route('/<id>')
    def show_pdf(id=None):
        if id is not None:
            return render_template('doc.html', doc_id=id)
    

    这嵌入了用户通过简单的 GET 请求从数据库请求的文档。希望这可以帮助任何在数据库中处理大量 PDF 的人!

    【讨论】:

    • make_response 给出错误:TypeError: 'file' object is not callable |有什么问题?
    【解决方案5】:

    你有两个选择。您可以渲染使用静态 PDF 文件的模板或渲染生成 PDF 的模板。我个人会选择第一个选项。

    This SO question is dedicated to how to write an HTML page that returns a PDF. You can use this in your jinja2 template.

    这里有一个快速而肮脏的方法来完成它。

    <embed src="http://yoursite.com/the.pdf" width="500" height="375">
    

    或者,您可以创建一个 jinja2 模板,该模板设置返回 PDF 所需的所有标题,然后说,

    <img src="{{ url_for('static', filename='img.png', _external=True) }}" />
    

    带有一个名为 static 的视图函数,它返回 pdf。

    You can read more about the second option at this flask snippet

    【讨论】:

    • 使用“快速而肮脏的方式”,src 可以只是我程序文件夹根目录中的 pdf 文档,还是必须链接到 URL?谢谢!
    • 可以只是pdf。 you can use relative paths from whatever folder the template is called from。所以如果你的结构是app-&gt;templates-&gt;PDFTemplate.html,你的文件在app-&gt;pdf.pdf,那么你可以说src="../pdf.pdf"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2015-06-29
    • 1970-01-01
    • 2013-11-25
    相关资源
    最近更新 更多