Модуль fpdf2
поддерживает базовый рендеринг из HTML. Другими словами fpdf2
поддерживает конвертацию/преобразование HTML-разметки в PDF-документ. Это очень удобно, когда надо быстро создать небольшой и не сложный PDF-документ.
Разбор HTML реализуется с помощью класса html.parser.HTMLParser
из стандартной библиотеки Python, а преобразование в PDF происходит с помощью класса fpdf.HTMLMixin
. Конечно, вся спецификация HTML не поддерживается, CSS не поддерживается от слова "совсем". В общем преобразование HTML-разметки в PDF-документ работает не стабильно и не совсем так как ожидаешь, но отчеты об ошибках и предложения по улучшению командой разработчиков приветствуются.
Поддерживаемые HTML-теги модулем fpdf2
:
<h1>
до <h8>
: заголовки и его атрибут выравнивания align
;<p>
: абзац и его атрибут выравнивания align
;<br>
: перенос строки;<b>
, <i>
, <u>
: жирный шрифт, курсив, подчеркивание (и их сочетание);<font>
: установка шрифта для HTML и его атрибуты face
, size
, color
;<center>
для выравнивания по центру;<a>
: ссылка и его атрибут href
;<img>
: изображения и атрибуты тега src
, width
, height
;<ol>
, <ul>
, <li>
: упорядоченные, неупорядоченные элементы и элементы списка (могут быть вложенными);<table>
: тег таблицы и его атрибуты border=1
, width
;<thead>
: заголовки колонок таблицы;<tbody>
: фактические строки с колонками;<tfoot>
: нижний колонтитул (должен завершать строки с колонками, используется перед закрывающим </table>
);<th>
: заголовки ячейки с ее атрибутами align
, bgcolor
, width
;<tr>
: строка таблицы с атрибутом bgcolor
;<td>
: ячейка с ее атрибутами align
, bgcolor
, width
;Важно:
<table>
может иметь атрибут width
, указанный только в процентах от ширины листа. При этом таблица центрируется по середине. Если ширина width
не указана, то таблица выравнивается по левому краю.<th>
с указанием атрибута ширины width
каждой колонки (указывается в %
или единицах, указанных при создании объекта FPDF
(по умолчанию unit="mm"
миллиметры). <table>
атрибута border=1
(отображение рамки) в сочетании с центрированием, например width=80%
, для корректного отображения нижней границы, последняя строчка таблицы, перед ее закрытием должна содержать пустой подвал <tfoot><tr></tr></tfoot>
.Примечание: Для более надежного и полнофункционального преобразования HTML5 + CSS3 в PDF-документ на Python можно использовать сторонний модуль WeasyPrint
, PyPi. Модуль имеет много зависимостей, но делает потрясающие PDF-документы из HTML.
fpdf2
.from fpdf import FPDF, HTMLMixin, __version__ as ver print('Версия FPDF2:', ver) # наследуемся от классов FPDF и HTMLMixin # - класс FPDF для создания PDF-документа # - класс HTMLMixin содержит парсер HTML class HTML_PDF(FPDF, HTMLMixin): pass # создаем экземпляр pdf = HTML_PDF() # директория где лежат системные шрифты OS Linux font_dir = '/usr/share/fonts/truetype/freefont' # добавляем TTF-шрифты, поддерживающие кириллицу. # шрифт FreeSerif pdf.add_font("Serif", style="", fname=f"{font_dir}/FreeSerif.ttf", uni=True) pdf.add_font("Serif", style="B", fname=f"{font_dir}/FreeSerifBold.ttf", uni=True) pdf.add_font("Serif", style="I", fname=f"{font_dir}/FreeSerifItalic.ttf", uni=True) pdf.add_font("Serif", style="BI", fname=f"{font_dir}/FreeSerifBoldItalic.ttf", uni=True) # шрифт FreeSans pdf.add_font("Sans", style="", fname=f"{font_dir}/FreeSans.ttf", uni=True) pdf.add_font("Sans", style="B", fname=f"{font_dir}/FreeSansBold.ttf", uni=True) pdf.add_font("Sans", style="I", fname=f"{font_dir}/FreeSansOblique.ttf", uni=True) pdf.add_font("Sans", style="BI", fname=f"{font_dir}/FreeSansBoldOblique.ttf", uni=True) # устанавливаем шрифт по умолчанию pdf.set_font("Serif", size=13) # добавляем страницу pdf.add_page() # печатаем HTML pdf.write_html(""" <h1>Название документа</h1> <h2>Название раздела</h2> <p><u>Добро</u> <i>пожаловать</i> в сторонний <b>модуль FPDF2</b>.</p> <p><a href="https://docs-python.ru">Справочник Python3.</a></p> <p align="right">Это текст, выровненный по правому краю</p> <p>Это параграф <br>состоящий из 2-х частей без атрибута "align" (имеет перенос строки "br").</p> <p align="center">Это параграф, состоящий из 2-х частей и имеющий атрибут "align" и не имеет переноса строки "br").</p> <p>Это <font color="green">зеленый</font> цвет (color="green")</p> <p>Это цвет <font color="#00ff00">color="#00ff00"</font></p> <p>Это шрифт размером <font size="9">9 пунктов (size="9")</font></p> <p><font face="Sans">Это подключенный шрифт FreeSans (face="Sans")</font></p> <h2>Другое название раздела</h2> <ul><li>неупорядоченные</li><li>элементы</li><li>списка</li></ul> <ol><li>пронумерованные</li><li>элементы</li><li>списка</li></ol> <br> <blockquote>Это цитата из HTML-блока "blockquote"</blockquote> <p>Выводим таблицу:</p> <table border="1"> <thead> <tr bgcolor="silver"> <th width="15">ID</th><th width="45">Имя</th> </tr> </thead> <tbody> <tr><td>1</td><td>Алиса</td></tr> <tr><td>2</td><td>Боб</td></tr> </tbody> <tfoot><tr></tr></tfoot> </table> <center>Выводим таблицу с центрированием по середине. Таблица занимает 60% от ширины листа:</center> <table border="1" width="60%"> <thead> <tr bgcolor="yellow"> <th width="20%">ID</th><th width="80%">Имя</th> </tr> </thead> <tbody> <tr><td>1</td><td>Алиса</td></tr> <tr><td>2</td><td>Боб</td></tr> </tbody> <tfoot><tr></tr></tfoot> </table> """, ul_bullet_char='-', table_line_separators=True) pdf.output("html.pdf")
FPDF.write_html()
Метод FPDF.write_html()
разбирает HTML и преобразует его в PDF-документ.
Синтаксис:
pdf.write_html(html_text, image_map=None, li_tag_indent=5, table_line_separators=False, ul_bullet_char='\x95', heading_sizes=None)
Описание аргументов:
html_text
: HTML-разметка, которую нужно добавить в PDF-документ;image_map=None
: необязательная функция с одним аргументом, которая сопоставляет src
с URL-адресами новых изображений;li_tag_indent=5
: отступ от символа элемента списка <li>
;table_line_separators=False
: включает/отключает разделители горизонтальных линий в таблице;ul_bullet_char='\x95'
: символ для элемента списка <li>
;heading_sizes=None
: