Вывод PDF-файлов с помощью Django

Этот документ объясняет, как динамически выводить 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.
  • Когда as_attachment=True передается параметру FileResponse, он устанавливает соответствующий заголовок Content-Disposition, который указывает веб-браузерам на появление диалогового окна с запросом/подтверждением того, как обрабатывать документ, даже если на машине установлено значение по умолчанию. Если параметр as_attachment опущен, браузеры будут обрабатывать PDF с помощью любой программы/плагина, который они настроили для работы с PDF.
  • Вы можете предоставить произвольный параметр filename. Он будет использоваться браузерами в диалоге «Сохранить как…».
  • Вы можете подключиться к API ReportLab: Тот же буфер, переданный в качестве первого аргумента в canvas.Canvas, можно передать в класс FileResponse.
  • Обратите внимание, что все последующие методы генерации PDF вызываются на объекте PDF (в данном случае p) - не на buffer.
  • Наконец, важно вызвать showPage() и save() в PDF-файле.

Примечание

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

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

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

См.также

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

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