Flask handling a PDF as its own page

前端 未结 5 1426
有刺的猬
有刺的猬 2020-12-14 08:52

For my personal website, I want to have a separate page just for my résumé, which is a PDF. I\'ve tried multiple ways, but I can\'t figure out how to get flask to handle a P

相关标签:
5条回答
  • 2020-12-14 09:07

    A note for anyone that came to this question because they're trying to serve PDF files from a database with Flask. Embedding a PDF when the file is stored on a database isn't as simple as when it's in the static folder. You have to use the make_response function and give it the appropriate headers so the browser knows what to do with your binary PDF data, rather than just returning it from the view function like normal. Here's some pseudocode to help:

    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
    

    You can change the Content-Disposition from 'inline' to 'attachment' if you want the file to download rather than display in the browser. You could also put this view in a subdomain, e.g. docs.yourapp.com rather than yourapp.com/docs. The last step is to actually embed this document in the browser. On any page you'd like, just use rawrgulmuffin's strategy:

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

    You could even make the src dynamic with a Jinja2 template. Let's put this in doc.html (note the curly brackets):

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

    Then in a view function, you just return the rendered template with the appropriate 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)
    

    This embeds a document the user requested from a database with a simple GET request. Hope this helps anyone working with lots of PDFs in a database!

    0 讨论(0)
  • 2020-12-14 09:16

    You can use flask send_file or send_static_file function in 5 lines:

    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 is helpful

    Also can use send_from_directory if you want send file from certain 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 about send_from_directory

    0 讨论(0)
  • 2020-12-14 09:22

    If your trying to do your typical

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

    where the user clicks on the link and the pdf is downloaded, you need to put your documents in your static folder.

    then you end up with something like:

    <a href="../static/doc.pdf">My Resume</a>
    
    0 讨论(0)
  • 2020-12-14 09:25

    You have two options. You can either render a template that uses a static PDF file or render a template that generates a PDF. I'd personally go with the first option.

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

    Here's a quick and dirty way to get it done.

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

    Or, you can create a jinja2 template which sets all the headers required to return a PDF and then say,

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

    with a view function called static that returns the pdf.

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

    0 讨论(0)
  • 2020-12-14 09:28

    I know it's quite late, but I just found the easiest way and it's not among those.

    Just redirect to the file's path as a static file, with any hyperlink:

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

    Or, if you want a maybe cleaner way... I just made a flask page for the pdfs like this:

    @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
    

    ...which I guess is kinda like giving a variable name to the pdf link (?), and also should be easier to adapt if I need to send the user to different pdfs depending on a variable.

    I'm thinking something in this lines:

    @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
    

    BTW: I'm working on pythonAnywhere, so I had to first define the path to the static files in the Web tab, so I could show static files to the user.

    0 讨论(0)
提交回复
热议问题