2013-08-16 11 views
8

Dla mojej osobistej strony internetowej, chcę mieć oddzielną stronę tylko dla mojego CV, który jest plikiem PDF. Próbowałem na wiele sposobów, ale nie wiem, jak uzyskać kolbę do obsługi pliku PDF.Flask obsługuje PDF jako własną stronę

Dzięki. Daj mi znać, jeśli chcę lepiej wyjaśnić, co próbuję zrobić.

+0

Czy można uzyskać serwer WWW do statycznego wyświetlania pliku (tak jak prawdopodobnie robisz dla swoich plików '/ static' mimo to). Jeśli tak, czy możesz utworzyć łącze w aplikacji Flask do pliku statycznego? –

Odpowiedz

4

Masz dwie opcje. Możesz albo renderować szablon, który używa statycznego pliku PDF, albo renderować szablon generujący plik PDF. Osobiście skorzystam z pierwszej opcji.

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

Oto szybki i brudny sposób, aby to zrobić.

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

Lub można utworzyć szablon jinja2 który określa wszystkie nagłówki wymaganych do powrotu PDF, a następnie powiedzieć,

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

z widokiem funkcję o nazwie Static zwracającej pdf.

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

+0

W "szybkiej i brudnej drodze", czy src może być tylko dokumentem pdf w katalogu głównym mojego folderu lub czy musi zawierać link do URL? Dzięki! –

+0

Może to być tylko plik pdf. [możesz użyć względnych ścieżek z dowolnego folderu, z którego wywoływany jest szablon] (http://stackoverflow.com/questions/7503130/relative-path-or-url-for-html-src-and-href-attributes). Więc jeśli twoja struktura to 'app-> templates-> PDFTemplate.html', a twój plik znajduje się w' app-> pdf.pdf', to możesz powiedzieć 'src =" ../ pdf.pdf "'. – AlexLordThorsen

20

Uwaga dla każdego, kto przyszedł na to pytanie, ponieważ próbują służyć plików PDF z bazy danych z kolbą. Osadzanie pliku PDF, gdy plik jest przechowywany w bazie danych, nie jest tak proste jak w folderze statycznym. Musisz użyć funkcji make_response i nadać jej odpowiednie nagłówki, aby przeglądarka wiedziała, co zrobić z binarnymi danymi PDF, a nie tylko zwracała je z funkcji widoku, jak normalnie. Oto niektóre Pseudokod pomóc:

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 

Można zmienić Content-Disposition z „inline” do „przywiązania”, jeśli chcesz pobrać plik zamiast wyświetlania w przeglądarce. Możesz też umieścić ten widok w poddomenie, np. docs.yourapp.com zamiast yourapp.com/docs. Ostatnim krokiem jest faktyczne osadzenie tego dokumentu w przeglądarce. Na każdej stronie, którą chcesz, wystarczy użyć strategii rawrgulmuffin za:

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

Można nawet zrobić src dynamiczny z szablonem Jinja2. Ujmę to w doc.html (zwróć uwagę na klamrowych):

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

Następnie w funkcji widoku, po prostu wrócić renderowany szablon z odpowiednim 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) 

To osadza udokumentować użytkownik żądany z bazy danych za pomocą prostego żądania GET. Mam nadzieję, że to pomoże każdemu pracować z dużą ilością plików PDF w bazie danych!

+0

make_response daje błąd: TypeError: obiekt 'file' nie jest możliwy do wywołania | co może być nie tak? – moaglee

3

Można użyć kolby send_file lub send_static_file funkcję w linii:

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 jest pomocne

Ponadto można używać send_from_directory jeśli chcesz wysłać plik z określonego katalogu:

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 o send_from_directory

+0

Byłoby lepiej użyć 'with', aby otworzyć plik, który upewnia się, że plik jest zamknięty po użyciu. –

+0

Dobrze, dzięki @ Audrius-Kažukauskas – Mohsen

Powiązane problemy