Создание PDF из HTML шаблона с помощью Python
Довольно часто возникает необходимость сгенерировать PDF файл скриптом на Python, например у меня недавно возникла такая задача:
Необходимо добавить в систему управления предприятием функционал формирования дипломов для наград сотрудников в виде PDF файлов, чтобы можно было их распечатать или послать по почте.
Порядок работы должен быть таким:
- Менеджер, через веб-форму, вводит необходимые данные (имя сотрудника, должность и т.п.);
- Далее он выбирает шаблон диплома (шаблоны заранее подготавливаются в системе);
- Получает сформированный PDF файл.
Погуглив нашел для себя несколько способов решить задачу:
1. Использовать Python библиотеку для формирования PDF, например reportlab;
2. Сначала сформировать HTML страницу с помощью какого-нибудь шаблонизатора, а потом уже конвертировать HTML в PDF.
Первый вариант мне показался сложноватым из-за форматирования, нужно будет рисовать и позиционировать каждый элемент шаблона используя код python. По этой же причине в будущем будут сложности с поддержкой шаблонов.
Я выбрал второй вариант, поскольку HTML шаблон для моей задачи был простой и не должно было возникнуть сложности в его конвертации в PDF. В качестве шаблонизатора, я использовал Jinja
Для конвертации HTML в PDF я использовал Python-PDFKit (для его работы в вашу систему необходимо установить wkhtmltopdf).
Чтобы показать пример, я максимально упрощу задачу. Пусть нам необходимо, чтобы скрипт брал имя пользователя из переменной и подставлял его в HTML шаблон, а дальше мы бы получали PDF файл с текстом «Привет <имя пользователя>»!
Для начала установим все необходимое:
pip install pdfkit
pip install Jinja2
Так же необходимо скачать и установить в систему wkhtmltopdf.
Для этой заметки, я устанавливать не стал, а скачал portable версию для Windows и распаковал ее в D:\wkhtmltox (этот путь понадобится в дальнейшем).
Создаем шаблон для формирования PDF
Для нашей задачи HTML шаблон будет максимально примитивный, создадим файл pdf_template.html:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hi</title>
</head>
<body>
<h1>Привет {{ name }}!</h1>
</body>
</html>
Здесь name — это переменная, которую мы будем передавать в шаблон.
Теперь нужно написать код python, который сгенерирует html шаблон. Как я уже писал мы используем шаблонизатор Jinja.
Создадим файл pdf.py:
from jinja2 import Environment, FileSystemLoader
name = 'Александр'
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template("pdf_template.html")
pdf_template = template.render({'name': name})
Сейчас в переменной pdf_template генерируется HTML шаблон:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hi</title>
</head>
<body>
<h1>Привет Александр!</h1>
</body>
</html>
Осталось сделать из него пдф.
Создаем PDF используя pdfkit
Осталось добавить к нашему скрипту пару строк и уже можно получить готовый пдф файл по нашему шаблону:
Сначала импортируем pdfkit:
import pdfkit
И одной строчкой сформируем pdf:
pdfkit.from_string(pdf_template, 'out.pdf')
Теперь, если выполнить скрипт, в папке появиться файл out.pdf созданный по нашему шаблону.
Поскольку я скачал portable версию wkhtmltopdf и пути к нему нет в переменной PATH, код нужно немного изменить, добавив путь к wkhtmltopdf.exe:
config = pdfkit.configuration(wkhtmltopdf=r’D:\wkhtmltox\bin\wkhtmltopdf.exe’)
pdfkit.from_string(pdf_template, ‘out.pdf’, configuration=config)
Итоговый код выглядит так:
from jinja2 import Environment, FileSystemLoader
import pdfkit
name = 'Александр'
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template("pdf_template.html")
pdf_template = template.render({'name': name})
pdfkit.from_string(pdf_template, 'out.pdf')
# config = pdfkit.configuration(wkhtmltopdf=r'D:\wkhtmltox\bin\wkhtmltopdf.exe')
# pdfkit.from_string(pdf_template, 'out.pdf', configuration=config)
На этом все 🙂