Как создавать файлы PDF

Этот документ объясняет, как динамически выводить PDF-файлы с помощью представлений Django. Это стало возможным благодаря отличной библиотеке ReportLab Python PDF с открытым исходным кодом.

Преимущество динамической генерации PDF-файлов заключается в том, что вы можете создавать индивидуальные PDF-файлы для различных целей - скажем, для разных пользователей или разных частей содержимого.

Например, Django использовался на сайте kusports.com для создания индивидуальных, удобных для печати скобок турнира NCAA в формате PDF для людей, участвующих в конкурсе «Мартовское безумие».

Установите ReportLab

Библиотека ReportLab - это available on PyPI. Руководство user guide (не случайно, в виде PDF-файла) также доступно для загрузки. Вы можете установить ReportLab с помощью pip:

$ python -m pip install reportlab
...\> py -m pip install reportlab

Проверьте свою установку, импортировав ее в интерактивный интерпретатор Python:

>>> import reportlab

Если эта команда не вызывает никаких ошибок, значит, установка прошла успешно.

Напишите свое мнение

Ключ к динамической генерации PDF с помощью Django заключается в том, что API ReportLab работает с файлоподобными объектами, а объекты Django FileResponse принимают файлоподобные объекты.

Вот пример «Hello World»:

import io
from django.http import FileResponse
from reportlab.pdfgen import canvas

def some_view(request):
    # Create a file-like buffer to receive PDF data.
    buffer = io.BytesIO()

    # Create the PDF object, using the buffer as its "file."
    p = canvas.Canvas(buffer)

    # Draw things on the PDF. Here's where the PDF generation happens.
    # See the ReportLab documentation for the full list of functionality.
    p.drawString(100, 100, "Hello world.")

    # Close the PDF object cleanly, and we're done.
    p.showPage()
    p.save()

    # FileResponse sets the Content-Disposition header so that browsers
    # present the option to save the file.
    buffer.seek(0)
    return FileResponse(buffer, as_attachment=True, filename='hello.pdf')

Код и комментарии должны быть понятны, но несколько моментов заслуживают упоминания:

  • В ответе автоматически устанавливается MIME-тип application/pdf на основе расширения имени файла. Это сообщает браузерам, что документ является PDF файлом, а не HTML файлом или обычным бинарным содержимым application/octet-stream.
  • When as_attachment=True is passed to FileResponse, it sets the appropriate Content-Disposition header and that tells web browsers to pop-up a dialog box prompting/confirming how to handle the document even if a default is set on the machine. If the as_attachment parameter is omitted, browsers will handle the PDF using whatever program/plugin they’ve been configured to use for PDFs.
  • Вы можете предоставить произвольный параметр filename. Он будет использоваться браузерами в диалоге «Сохранить как…».
  • Вы можете подключиться к API ReportLab: Тот же буфер, переданный в качестве первого аргумента в canvas.Canvas, можно передать в класс FileResponse.
  • Обратите внимание, что все последующие методы генерации PDF вызываются на объекте PDF (в данном случае p) - не на buffer.
  • Наконец, важно вызвать showPage() и save() в PDF-файле.

Примечание

ReportLab не является потокобезопасным. Некоторые наши пользователи сообщали о странных проблемах с созданием Django представлений, генерирующих PDF, к которым одновременно обращается множество людей.

Другие форматы

Обратите внимание, что в этих примерах нет ничего специфичного для PDF - только биты, использующие reportlab. Вы можете использовать аналогичную технику для генерации любого произвольного формата, для которого вы можете найти библиотеку Python. Также смотрите Как создать выходной файл CSV для другого примера и некоторых приемов, которые можно использовать при генерации текстовых форматов.

См.также

Django Packages предоставляет comparison of packages, который помогает генерировать PDF файлы из Django.

Вернуться на верх