Как создавать PDF файлы¶
Здесь рассказывается как генерировать PDF с помощью представлений Django. Это возможно благодаря чудесной открытой библиотеке ReportLab.
Преимущество динамической генерации PDF заключается в том, например, что вы можете создавать разные документы для разных пользователей.
Например, Django использовали на kusports.com для генерации турнирной таблицы NCAA, которую можно распечатать как обычный PDF-файл.
Установка ReportLab¶
Библиотека ReportLab доступна на PyPI. Документация не случайно это PDF файл) также доступна для загрузки. Вы можете установить ReportLab с помощью pip:
$ python -m pip install reportlab
...\> py -m pip install reportlab
Проверьте правильность установки с помощью импорта в интерактивном интерпретаторе:
>>> import reportlab
Если не вылезло никакой ошибки, значит установка прошла успешно.
Пишем собственное представление.¶
Ключевым фактором в динамической генерации PDF с помощью Django является то, что ReportLab API работает с файловыми объектами, также, как и 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")
Код и комментарии должны быть понятны, но на некоторые вещи стоит обратить внимание:
Ответу устанавливается специальный тип application/pdf. Этим мы говорим браузеру, что результат запроса - документ PDF, а не HTML файл. Если этого не сделать, то браузер может попытаться интерпретировать его как HTML, что приведёт к ужасным, страшным абракадабрам в окне браузера.
Когда
as_attachment=Trueпередается вFileResponse, он устанавливает соответствующий заголовокContent-Disposition, который сообщает веб-браузерам, что нужно открыть диалоговое окно с запросом/подтверждением того, как обрабатывать документ, даже если на машине установлен параметр по умолчанию. Если параметрas_attachmentпропущен, браузеры будут обрабатывать PDF-файл с помощью любой программы/плагина, которые они настроили для использования с PDF-файлами.Вы можете указать произвольный параметр
filename. Он будет использоваться браузерами в диалоговом окне «Сохранить как…».Подключить ReportLab довольно просто: просто передайте
responseв качестве первого аргумента вcanvas.Canvas. КлассCanvasожидает любой файловый объект, аHttpResponseкак раз прекрасно подходит на данную роль.Следует отметить, что все последующие действия нужно производить с получившимся объектом (в данном случае с
p), а не сresponse.Наконец, важно вызвать
showPage()иsave().
Примечание
ReportLab не потокобезопасна. Пользователи могут мешать друг другу в процессе построения PDF.
Другие форматы¶
Обратите внимание, что не так много специфики PDF в генерации документов - для ReportLab это всего лишь биты. Вы можете использовать подобную технику для генерации файла любого формата для которого есть соответствующая библиотека. В Генерация CSV на Django есть ещё примеры создания текстового формата.
См.также
Django Packages предоставляет сравнение библиотек для создания PDF файлов.