Организация Meta, владеющая соцсетями Instagram и Facebook, признана в России экстремистской и запрещена в РФ

WeasyPrint: где скачать и как пользоваться

2026-09-12 18:23:48 Время чтения 46 мин 7

WeasyPrint нужен там, где PDF должен собираться из HTML-шаблона предсказуемо и автоматически: из отчёта, счёта, билета, инструкции или книги. На странице Xeon Live можно скачать WeasyPrint бесплатно, а в этом материале разберём рабочую схему от первого запуска до печатного CSS, Python API, диагностики и серверной автоматизации.

Что такое WeasyPrint и где он полезен

Что делает движок и для кого он рассчитан

Пример результата: текст, таблица и ссылка остаются частью обычного PDF

WeasyPrint — движок печатной вёрстки, который читает HTML, применяет CSS и экспортирует раскладку в PDF. Он не строится вокруг визуального холста и не предлагает редактировать уже готовый PDF мышью. Основные пользователи — разработчики, технические специалисты и команды, у которых документ формируется из данных: счета из CRM, отчёты из аналитической системы, сертификаты, билеты, инструкции, каталоги и другие повторяемые публикации.

Сильная сторона подхода — отделение данных от оформления. Шаблон можно держать в системе контроля версий, стили менять так же, как стили веб-страницы, а выпуск запускать одной командой или из Python. Это особенно полезно, когда один и тот же макет создаётся десятки или тысячи раз с разными значениями. В таком процессе PDF перестаёт быть вручную собранным файлом и становится конечным артефактом воспроизводимой сборки.

WeasyPrint ориентирован именно на печатную модель CSS. Правило @page управляет размером листа, полями и областями колонтитулов, счётчики дают номера страниц, свойства разрыва управляют пагинацией, а обычные HTML-заголовки могут превращаться в закладки. При этом движок не является полноценным браузером: он не нужен для выполнения клиентской логики приложения, а ценность даёт прежде всего там, где содержимое уже сформировано и его требуется аккуратно разложить по страницам.

Текущая версия, лицензия и требования

Актуальный релиз 70.0: Python 3.10+, BSD-лицензия, выпуск 8 сентября 2026 года

Актуальная версия — WeasyPrint 70.0. Выпуск 70.0 опубликован 8 сентября 2026 года и включает исправления безопасности, поэтому для рабочего сервера имеет смысл ориентироваться именно на свежий релиз, а не фиксировать старую сборку без причины. Проект распространяется по лицензии BSD, рассчитан на Python 3.10 и новее и использует Pango для работы со шрифтами и текстовой раскладкой.

Для пользователя важнее не номер версии сам по себе, а воспроизводимость среды. После установки сохраните вывод weasyprint --info рядом с диагностикой вашего проекта или в журнале сборки. При расхождении версий Pango, шрифтов или самого WeasyPrint один и тот же шаблон способен выглядеть чуть иначе. Особенно это заметно на границах страниц, в таблицах с длинным текстом и в документах, где одна строка решает, поместится ли блок на листе.

Карта интерфейса: где находится управление

Командная строка и справка

Основной интерфейс WeasyPrint — CLI: входной HTML, выходной PDF и параметры рендера

У программы нет главного окна. Практическая карта управления состоит из четырёх частей: команда weasyprint, исходный HTML, таблицы стилей и готовый PDF. Справка weasyprint --help показывает доступные параметры: пользовательские стили, вложения, варианты PDF, формы, оптимизацию изображений, DPI, base URL, тип media, режимы журнала и другие настройки. Такой интерфейс выглядит аскетично, зато хорошо переносится в скрипты, CI и серверные задачи.

В повседневной работе полезно разделить параметры на две группы. Геометрию страницы, колонтитулы, разрывы, типографику и большую часть внешнего вида лучше хранить в CSS. Параметры запуска оставляют для конкретной сборки: дополнительная таблица стилей, качество JPEG, максимальное DPI, формат специального PDF, папка кэша, ограничения сетевых обращений и подробность журнала. Так шаблон остаётся читаемым, а команда запуска не превращается в длинный набор случайных флагов.

Цикл HTML/CSS → PDF и проверка результата

После рендера проверяйте число страниц, формат листа и свойства PDF, а не только факт появления файла

Рабочий цикл обычно выглядит так: открыть шаблон в редакторе кода, изменить HTML или CSS, выполнить рендер, открыть PDF в просмотрщике, проверить критичные страницы и повторить. Диагностические сообщения терминала — часть интерфейса: предупреждение о недоступном изображении или проигнорированном свойстве часто быстрее указывает на причину, чем визуальный поиск по десяткам страниц.

Не ограничивайтесь первой страницей. Пагинация ломается на длинных таблицах, в конце главы, рядом с крупным изображением и при появлении необычно длинного значения из данных. Для серьёзного шаблона полезно держать три тестовых набора: короткий, типовой и предельный. Они позволяют увидеть и лишние пустые страницы, и наложение колонтитула, и слишком узкую колонку до того, как ошибка попадёт в массовую генерацию.

Как установить WeasyPrint и создать первый PDF

Установка и проверка окружения

После установки убедитесь, что WeasyPrint видит Python, Pango и системное окружение

Начните с способа установки, который соответствует системе. В Linux WeasyPrint есть в пакетах ряда дистрибутивов, macOS предлагает установку через Homebrew, а на Windows самый прямой путь для командной работы — готовый executable актуального выпуска. Для использования как Python-библиотеки на Windows отдельно требуется окружение с Pango; документация описывает вариант через MSYS2 UCRT64. На Linux и macOS библиотеку часто ставят в виртуальное окружение через pip после подготовки системных зависимостей.

  1. Создайте отдельный каталог проекта и виртуальное окружение Python, чтобы версия WeasyPrint и его Python-зависимостей не смешивалась с другими приложениями.
  2. Активируйте окружение и установите WeasyPrint. На сервере фиксируйте версию в файле зависимостей, чтобы обновление происходило управляемо.
  3. Выполните weasyprint --info. Сохраните в журнале версию WeasyPrint, Python и Pango: эти значения пригодятся при сравнении окружений.
  4. Если команда не запускается, сначала исправьте системную зависимость или путь к библиотеке. Не переходите к отладке CSS, пока базовый запуск не стабилен.
  5. На Windows при сообщениях о недоступной DLL проверьте каталог MSYS2 и переменную WEASYPRINT_DLL_DIRECTORIES; на macOS при проблемах с динамическими библиотеками сверяйте путь Homebrew.

Контрольная точка после установки проста: weasyprint --info завершается без ошибки. Только после этого создавайте тестовый документ. Такой порядок экономит время: проблема загрузки Pango и проблема неверного CSS требуют совершенно разных действий, и смешивать их в одной диагностике не стоит.

Первый PDF и контроль готового файла

После первой генерации проверьте число страниц, размер листа, размер файла и версию PDF

Для первого теста создайте минимальный UTF-8 HTML с языком документа и явным @page. Не начинайте с боевого шаблона на сотни строк: короткий документ позволяет сразу понять, работает ли рендер, видны ли шрифты и применяются ли стили.

  1. Создайте файл sample.html с doctype, html lang="ru", meta charset="utf-8", заголовком и несколькими абзацами.
  2. Добавьте в style правило @page { size: A4; margin: 18mm; } и базовый шрифт body. Это зафиксирует геометрию листа.
  3. В терминале из каталога проекта выполните weasyprint sample.html sample.pdf. Первый аргумент — источник, второй — файл результата.
  4. Откройте sample.pdf и увеличьте текст. Буквы должны оставаться резкими при большом масштабе, потому что обычный текст выводится как текст, а не как растр.
  5. Проверьте число страниц и размер листа. В Linux и macOS можно использовать pdfinfo; на других системах достаточно свойств PDF-просмотрщика.
  6. Измените одно заметное правило CSS, например размер заголовка, повторите команду и убедитесь, что PDF действительно обновился. Это исключит ситуацию, когда вы смотрите старый файл из другой папки.

Если файл появился, но стили выглядят не так, как в браузере, не делайте вывод о поломке движка. Печатная раскладка отличается от непрерывной веб-страницы: ширина ограничена листом, есть поля, разрывы и отдельные страницы. Следующим этапом настройте печатные правила, а не пытайтесь воспроизвести экранный интерфейс пиксель в пиксель.

Как настроить страницу, разрывы и колонтитулы

Размер страницы, ориентация и поля через @page

Размер, ориентация и поля документа задаются CSS, а не диалогом печати

Геометрию страницы храните в @page. Это центральное правило для печатного шаблона: оно делает формат листа частью кода и устраняет зависимость от настроек принтера или случайного диалога экспорта. WeasyPrint не предлагает отдельные CLI-флаги для ширины страницы и полей, потому что эти параметры относятся к CSS Paged Media.

  1. Задайте размер: @page { size: A4; }. Для альбомной ориентации используйте A4 landscape. Для нестандартного бланка можно указать две длины.
  2. Добавьте поля в физических единицах: margin: 15mm 12mm 18mm. Для печати миллиметры обычно понятнее пикселей.
  3. Отдельно оформите первую страницу через @page :first, если ей требуется другой верхний отступ, титульная шапка или отсутствие номера.
  4. Для разворотной книги используйте :left и :right, чтобы зеркально менять внутренние и внешние поля. Для электронного отчёта это обычно не требуется.
  5. Если в одном документе есть разные листы, создайте именованные страницы и назначайте элементам свойство page. Так широкая ведомость может перейти на альбомный лист, а основной текст остаться портретным.
  6. После изменения @page проверьте не только внешние края, но и доступную ширину содержимого. A4 минус левые и правые поля — это реальная ширина, в которую должны помещаться таблицы и карточки.

Не используйте глобальный scale как замену правильной геометрии. Масштабирование затрагивает и физические единицы, поэтому может испортить ожидаемый размер листа. Если таблица вылезает за край, найдите фиксированную ширину, непереносимую строку или слишком большой внутренний отступ вместо того, чтобы просто уменьшать весь документ.

Разрывы, колонтитулы и нумерация

Заголовок раздела можно переносить в верхний колонтитул, а номер страницы формировать счётчиками CSS

После геометрии настройте поток между страницами. Свойства break-before, break-after и break-inside управляют тем, где начинается новый лист и какие компактные блоки нельзя рвать. Orphans и widows уменьшают число одиночных строк на краях страниц. Для повторяющихся элементов используются margin boxes @page, счётчики page и pages, а для текущего заголовка — string-set или running elements.

  1. Поставьте break-after: avoid на заголовки, которые не должны оставаться последней строкой страницы без последующего текста.
  2. Используйте break-inside: avoid только для небольших смысловых блоков: подпись, карточка реквизитов, итог. Не запрещайте разрыв огромному контейнеру.
  3. Задайте orphans и widows для основного текста, затем проверьте короткие и длинные абзацы. Эти свойства помогают, но не заменяют тестирование реальных данных.
  4. Добавьте @bottom-center { content: "Страница " counter(page) " из " counter(pages); } для нумерации без предварительного знания длины документа.
  5. Чтобы показывать название текущего раздела, сохраните заголовок через string-set и выведите строку в @top-right или другой margin box.
  6. Проверьте страницу, где заголовок сменяется в самом низу листа. Именно на границах разделов чаще всего заметно, правильно ли обновляется running header.
  7. Для титульной страницы создайте отдельное @page :first и уберите обычную нумерацию либо замените её фирменной шапкой.

Если появляется почти пустая страница, временно уберите запреты на разрыв и посмотрите, какой блок вытесняет поток. Частая причина — попытка удержать целиком элемент, который физически почти равен высоте листа. Чем меньше область, на которую навешан запрет, тем устойчивее получается макет.

Как подключить CSS, изображения, шрифты и навигацию

Относительные пути и base URL

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

Пропавшие изображения почти всегда начинайте искать с базового адреса. Если WeasyPrint читает файл с диска, базой обычно становится каталог этого файла. Если HTML передан строкой из Python или через стандартный ввод, контекста каталога нет, поэтому относительным ссылкам требуется base_url или --base-url.

  1. Соберите шаблон в отдельном каталоге: document.html, css/, img/ и fonts/. Это упрощает перенос между разработчиком, контейнером и сервером.
  2. Сначала проверьте относительный путь обычным локальным файлом. Например, img/logo.svg должен реально существовать с тем же регистром букв.
  3. Если HTML формируется строкой, передайте base_url в HTML(string=..., base_url=...). Для CLI со stdin используйте --base-url.
  4. При сетевом ресурсе включите подробный журнал и проверьте не только HTTP-код, но и содержимое. Страница авторизации с кодом 200 не является картинкой.
  5. Критичные логотипы и шрифты храните рядом с шаблоном, когда доступность внешнего сервера не должна влиять на выпуск документа.
  6. Для закрытых ресурсов приложения используйте контролируемый URL fetcher, который умеет получить байты из нужного хранилища или добавить авторизацию, а не заставляйте шаблон обращаться к внутреннему сайту как обычный браузер.

На Linux учитывайте регистр имён. Шаблон, который находил Logo.svg на нечувствительной файловой системе, может потерять картинку при переносе в контейнер, где logo.svg и Logo.svg — разные файлы. Та же логика относится к таблицам стилей и файлам шрифтов.

Шрифты, кириллица и переносы

Язык документа и доступный шрифт влияют на переносы, набор и число строк на странице

WeasyPrint использует Pango и системный механизм поиска шрифтов. Для воспроизводимого делового шаблона лучше не полагаться на случайную гарнитуру рабочей станции. Если лицензия позволяет, храните файлы шрифта вместе с проектом и описывайте начертания через @font-face. Отдельно объявляйте regular, bold и другие реально используемые варианты.

  1. Сначала убедитесь, что выбранный файл содержит кириллицу, знак рубля и специальные символы, которые встречаются в данных. Проверка одной латинской фразы ничего не доказывает.
  2. Опишите семейство в @font-face и используйте одинаковое имя font-family во всех правилах. Следите за относительным путём к файлу.
  3. Задайте lang="ru" на корневом html или нужном фрагменте. Это влияет на языковые правила текста, в том числе на автоматические переносы.
  4. Для узких колонок включайте hyphens: auto точечно. В артикулах, кодах, адресах электронной почты и идентификаторах переносы обычно нежелательны.
  5. Сравните страницы с короткими и длинными строками. Замена шрифта меняет метрики и способна сдвинуть разрыв на следующую страницу даже при том же размере в пунктах.
  6. После стабилизации макета решайте, нужна ли полная вставка шрифта. По умолчанию подмножество часто даёт меньший файл; полные шрифты нужны только для конкретного процесса.

Как проверить, какой шрифт найден системой

fc-match помогает понять, какой файл Fontconfig отдаёт Pango для указанного семейства

Если вместо букв появляются квадраты или строки неожиданно стали шире, проверьте фактическое соответствие семейства. Команда fc-match показывает, какой системный файл найден для имени. Это особенно полезно в контейнере, где привычная гарнитура разработчика отсутствует, а Fontconfig подставляет другой шрифт.

  1. Выполните fc-match с тем же именем семейства, которое указано в CSS.
  2. Сравните результат на рабочей машине и сервере. Разные файлы шрифтов означают потенциально разные метрики строк.
  3. Если нужен строго одинаковый вид, подключите конкретный файл @font-face и включите его в образ приложения или пакет шаблона.
  4. Повторите рендер и проверьте самые длинные строки, подписи в таблицах и границы страниц. Именно там разница метрик проявляется раньше всего.

Таблицы, Flexbox и Grid

Таблицы подходят для данных, Grid и Flexbox — для компактных блоков, но сложные раскладки требуют проверки

Для табличных данных используйте настоящую таблицу HTML. Она лучше передаёт структуру строк и столбцов, а thead помогает повторять заголовок при переходе на новый лист. Flexbox в WeasyPrint работает для простых случаев, а Grid поддерживает большой набор свойств, но документация прямо отмечает ограничения и неполное покрытие сложных сценариев. Поэтому выбор раскладки должен следовать смыслу данных, а не моде веб-вёрстки.

  1. Для большой ведомости начните с table, thead, tbody и понятных ширин столбцов. Не имитируйте таблицу набором grid-карточек.
  2. Проверьте самое длинное значение без пробелов. Артикул или URL способен растянуть столбец и вытолкнуть таблицу за правое поле.
  3. Если ширины должны быть стабильными, используйте предсказуемый алгоритм таблицы и задавайте ограничения там, где это оправдано.
  4. Flexbox оставляйте для коротких горизонтальных групп: реквизитов, пары карточек, строки подписи. Следите за минимальной шириной дочерних элементов.
  5. Grid применяйте внутри компактной секции, которая гарантированно укладывается в разумную область. Для сложного перехода сетки через страницу обязательно создайте тест с максимальным содержимым.
  6. После любой правки проверьте лист, где таблица пересекает границу страницы: повторился ли заголовок, не отделился ли итог и не возникла ли пустая полоса.

Ссылки, закладки и метаданные

HTML-ссылки становятся активными, а заголовки могут формировать закладки PDF

WeasyPrint сохраняет полезную навигацию, если она заложена в HTML. Внутренняя ссылка на id остаётся переходом внутри PDF, внешняя ссылка становится кликабельной, а заголовки формируют дерево закладок. Метаданные можно передать из title и meta. Для длинной инструкции это делает PDF заметно удобнее без ручной доработки в редакторе.

  1. Назначьте уникальные id тем разделам, на которые должны вести внутренние ссылки. Повторяющиеся id приводят к неоднозначной цели.
  2. Соберите оглавление обычными ссылками на эти id. Для печатного оглавления добавьте target-counter, если требуется выводить номер страницы рядом с названием.
  3. Проверьте закладки в боковой панели PDF-просмотрщика. Иерархия h1–h6 должна быть логичной, без случайных скачков уровней.
  4. Добавьте title, author, description и другие нужные метаданные в head. Не помещайте конфиденциальные служебные поля в meta без необходимости.
  5. Откройте несколько ссылок после генерации. Проверяйте как внутренние переходы, так и абсолютные внешние URL.
  6. Если документ будут печатать, не полагайтесь только на кликабельность: критически важный адрес или идентификатор должен быть понятен и на бумаге.

Если нужен общий контекст по самому формату, полезно свериться с материалом Xeon Live о том, как устроен PDF и какие задачи решает формат. Это помогает отделить возможности рендера от возможностей последующего редактирования и просмотра.

Как использовать Python API и автоматизировать выпуск

Python API: HTML.write_pdf и строки в памяти

HTML.write_pdf позволяет писать PDF в файл или получать байты в памяти

CLI подходит для ручного запуска и оболочечных сценариев. Когда PDF является частью веб-приложения или сервиса, удобнее Python API. Центральный объект — HTML: ему можно передать имя файла, URL, файловый объект или строку. Метод write_pdf записывает результат в файл или возвращает байты, если путь не указан.

  1. Импортируйте HTML из weasyprint и определите источник. Для файла используйте HTML(filename="document.html"), для строки — HTML(string=html_text, base_url=base_path).
  2. Если шаблон ссылается на относительные картинки или CSS и HTML передаётся строкой, обязательно задайте base_url. Без него ресурсам не от чего вычислять путь.
  3. Вызовите write_pdf с именем файла для дискового результата. Для HTTP-ответа можно получить байты и передать их фреймворку без временного файла.
  4. Если нужно работать с отдельными страницами, сначала вызовите render. Объект Document даёт доступ к страницам, ссылкам, закладкам и метаданным.
  5. Не создавайте тяжёлое окружение заново для каждого документа без необходимости. Для большого потока выгоднее долгоживущий процесс, который повторно использует библиотеку.
  6. Логируйте идентификатор документа, длительность рендера, число страниц и размер файла. Это помогает отличить медленный шаблон от проблем сети или данных.

Для простой конвертации HTML в PDF можно также посмотреть пошаговый материал Xeon Live о преобразовании HTML в PDF. В нём WeasyPrint логично сравнивать с браузерными и настольными способами, когда важен именно пользовательский сценарий, а не интеграция в Python.

Автообновление и пакетный выпуск

Во время вёрстки файл можно пересобирать автоматически после сохранения исходников

При активной разработке вручную повторять одну и ту же команду неудобно. Документация предлагает связку с watchexec: утилита следит за HTML и CSS и заново запускает python -m weasyprint после изменения. В production подход другой: пакет документов формируется циклом приложения, очередью задач или отдельным worker-процессом.

  1. Во время разработки подключите наблюдение только к каталогам и расширениям шаблона, чтобы лишнее изменение не запускало тяжёлый рендер.
  2. После каждой автоматической сборки проверяйте время изменения PDF. Так видно, что наблюдатель действительно сработал, а просмотрщик не показывает кэшированную копию.
  3. Для пакетной генерации заранее создайте список входных данных и уникальные имена файлов. Не позволяйте двум задачам писать в один путь одновременно.
  4. Выделите временную директорию для промежуточных ресурсов и очищайте её после успешной или аварийной сборки.
  5. Ограничьте параллелизм. Печатная раскладка и обработка больших изображений потребляют память, поэтому десятки одновременных процессов могут замедлить систему сильнее, чем несколько контролируемых workers.
  6. Собирайте метрики: длительность, число страниц, размер PDF, количество предупреждений. Резкий рост одного показателя часто сигнализирует о новой тяжёлой картинке или неудачном CSS.
  7. Для критичных документов сохраняйте контрольный набор эталонных входов и периодически сравнивайте результаты после обновления WeasyPrint.

Ограничение сетевых ресурсов и URL fetcher

При недоверенном HTML сетевой доступ и локальные файлы нужно ограничивать отдельно от CSS-вёрстки

Серверный рендер нельзя считать безопасным только потому, что он создаёт PDF. WeasyPrint умеет читать локальные файлы и обращаться к сетевым URL, а недоверенный HTML способен использовать это для нежелательного доступа или создавать очень тяжёлые документы. Поэтому обработку пользовательской разметки изолируют и ограничивают.

  1. Разделите доверенные шаблоны приложения и пользовательский HTML. Для пользовательского содержимого применяйте отдельный процесс с лимитами памяти и времени.
  2. Ограничьте разрешённые протоколы. Если документу нужны только HTTPS-ресурсы, не оставляйте доступ к file:// и другим схемам по умолчанию.
  3. Задайте разумный timeout для сетевых загрузок. Внешний сервер не должен удерживать worker бесконечно.
  4. Используйте собственный URLFetcher, когда нужно разрешить только конкретные домены или виртуальные схемы приложения. Не передавайте сетевой доступ шире, чем требуется шаблону.
  5. Для локальных картинок сопоставляйте логические пути с контролируемой директорией, а не с произвольным путём из пользовательских данных.
  6. Считайте слишком большие CSS-значения и огромные документы отдельным риском. Лимиты процесса важны даже после фильтрации URL.
  7. После обновления WeasyPrint читайте security-раздел changelog: версия 70.0 сама является исправлением безопасности, поэтому обновления здесь имеют практическое значение.

Как управлять качеством, размером и специальными вариантами PDF

Оптимизация изображений, DPI и качество JPEG

Параметры optimize-images, jpeg-quality и dpi уменьшают файл, но результат нужно сравнивать визуально

Качество итогового PDF определяется прежде всего исходными ресурсами и геометрией, а не одним универсальным ползунком. Векторный текст и SVG обычно масштабируются хорошо. Основной источник лишнего веса — крупные растровые изображения и полные наборы шрифтов. CLI даёт отдельные параметры для оптимизации изображений, качества JPEG и максимального DPI.

  1. Сначала приведите исходные картинки к разумному физическому размеру. Фотография в несколько тысяч пикселей не нужна, если на странице она занимает маленькую карточку.
  2. Запустите базовый рендер без агрессивной оптимизации и сохраните его как визуальный ориентир.
  3. Включите --optimize-images для без потерь там, где движок может уменьшить избыточность.
  4. Для фотографий протестируйте jpeg-quality на копии документа. Снижение качества уменьшает размер, но мелкие детали и градиенты могут получить артефакты.
  5. Ограничьте DPI, если шаблон получает изображения с чрезмерным разрешением. Параметр не создаёт деталей в плохом исходнике и не заменяет нормальную подготовку картинок.
  6. Сравните два PDF на масштабе 100% и на увеличении. Проверьте логотипы, мелкий текст в изображениях, схемы и фотографии, затем измерьте экономию размера.
  7. Только после визуальной проверки закрепляйте параметры в production. Один набор настроек редко одинаково хорош для фотоотчёта и документа с графиками.

PDF/A, PDF/UA и PDF/X

WeasyPrint умеет запрашивать PDF/A, PDF/UA и PDF/X, но соответствие проверяют отдельным валидатором

WeasyPrint умеет генерировать специализированные варианты PDF через --pdf-variant или параметр Python API. Это полезно для архивного хранения, доступности и полиграфии. Однако выбранный флаг не исправляет исходный документ автоматически. Валидность зависит от HTML, семантики, шрифтов, цветов, метаданных и изображений, поэтому после рендера нужен профильный валидатор.

  1. Определите требуемый стандарт до вёрстки. PDF/A для архива, PDF/UA для доступности и PDF/X для печатного обмена предъявляют разные требования.
  2. Для PDF/UA начните с семантического HTML: правильной иерархии заголовков, подписей полей, альтернативного текста и языка документа.
  3. Для PDF/A убедитесь, что шрифты и цветовые условия соответствуют выбранному варианту. Не добавляйте возможности, которые стандарт запрещает.
  4. Для PDF/X согласуйте выходной цветовой профиль и требования типографии. В версии 69+ используется output intent вместо прежней опции srgb.
  5. Сгенерируйте файл нужным --pdf-variant, затем проверьте его специализированным валидатором. Успешное завершение WeasyPrint подтверждает рендер, а не полную нормативную проверку.
  6. Храните отчёт валидатора рядом с документом, когда соответствие стандарту является формальным требованием процесса.

Заполняемые PDF-формы

Опция --pdf-forms и appearance: auto позволяют создавать интерактивные поля поддерживаемых типов

По умолчанию элементы HTML-формы превращаются в статический внешний вид. Опция --pdf-forms или параметр pdf_forms включает интерактивные поля, а appearance: auto позволяет выбирать отдельные элементы. Поддержка формы зависит и от PDF-просмотрщика, поэтому один и тот же файл нужно проверять в тех клиентах, которыми действительно пользуются получатели.

  1. Сначала сверстайте форму как обычный HTML с label и понятными именами полей. Семантика важна и для доступности, и для последующей обработки.
  2. Решите, должны ли интерактивными быть все поля. Для выборочного режима применяйте appearance: auto к нужным input, textarea или select.
  3. Сгенерируйте PDF с --pdf-forms и откройте его в целевом просмотрщике.
  4. Проверьте фокус с клавиатуры, ввод длинного текста, состояние флажков, списки и печать заполненной формы.
  5. Убедитесь, что длинное значение не обрезается. Поле, которое выглядит аккуратно пустым, может оказаться слишком низким после ввода фамилии или номера.
  6. Если функциональность ведёт себя по-разному в двух программах чтения PDF, отделяйте ограничение просмотрщика от ошибки WeasyPrint прежде чем менять шаблон.

Как находить и исправлять типичные ошибки

Диагностика предупреждений и пропавших ресурсов

Подробный журнал показывает недоступные изображения и другие проблемы загрузки во время рендера

Ошибка рендера редко требует начинать шаблон заново. Сначала уменьшите проблему до короткого воспроизводимого HTML, затем включите подробный журнал и разделите сбой на одну из категорий: ресурс не найден, шрифт подменён, CSS не поддерживается, блок не помещается в доступную область или серверное обращение зависает. Такая классификация намного быстрее случайного изменения стилей.

  1. Пропала картинка. Проверьте base URL, точное имя файла, регистр, права чтения и MIME-тип ответа. Затем временно замените ресурс маленькой локальной картинкой: если она появилась, движок работает, проблема в загрузке.
  2. Пропали стили. Убедитесь, что stylesheet реально найден. Подключите критичное правило прямо в style и проверьте изменение. После этого возвращайте внешний CSS и ищите путь или каскад.
  3. Кириллица превратилась в квадраты. Проверьте fc-match и наличие нужных глифов. Подключите конкретный файл через @font-face, если системная подстановка непредсказуема.
  4. Таблица выходит за край. Найдите самую длинную непереносимую строку, фиксированные width/min-width и суммарные внутренние отступы. Увеличение формата листа — временная маскировка, а не исправление.
  5. Появилась пустая страница. Снимите break-inside: avoid с крупных контейнеров и проверьте высоту блока. Часто движок пытается сохранить вместе элемент, который почти равен странице.
  6. Документ отличается от браузера. Уберите зависимость от экранных состояний и интерактивной логики. Печатный CSS должен описывать статическую страницу самостоятельно.
  7. Рендер долго не заканчивается. Проверьте сетевые ресурсы, огромные изображения и чрезмерные CSS-значения. На сервере используйте timeout и лимиты процесса.
  8. После обновления изменились разрывы. Сравните версии WeasyPrint, Pango и шрифтов. Затем прогоните контрольный набор длинных документов и зафиксируйте нужные правки в шаблоне.

Для базовых операций с готовыми документами есть отдельные инструкции Xeon Live, например как создать PDF-файл разными способами. Это полезное разграничение: WeasyPrint силён именно как генератор из HTML/CSS, а не как универсальный редактор уже существующего PDF.

Плюсы, минусы и кому программа подойдёт

Плюсы, минусы и ограничения

Главный критерий выбора — наличие HTML/CSS-шаблона и потребность в автоматической генерации, а не ручном редактировании PDF

Плюсы

  1. HTML и CSS остаются знакомой средой для веб-разработчика; печатные особенности задаются стандартными правилами Paged Media.
  2. Один шаблон легко включить в повторяемый серверный процесс, CLI-задачу или Python-приложение.
  3. Поддерживаются страницы, колонтитулы, счётчики, ссылки, закладки, формы и специализированные варианты PDF.
  4. Проект свободный и распространяется по BSD-лицензии.
  5. Результат хорошо подходит для отчётов, счетов, билетов, книг, инструкций и других документов, которые строятся из структурированных данных.

Минусы

  1. Нет визуального редактора и привычного окна с холстом: для работы нужны HTML, CSS и терминал либо код.
  2. Печатный CSS требует отдельной отладки; сложный макет не стоит переносить из браузера без адаптации.
  3. Flexbox и Grid подходят не для всех сложных случаев, а часть веб-CSS не поддерживается или ведёт себя иначе.
  4. Сетевые ресурсы, локальные файлы и недоверенный HTML требуют продуманной изоляции в серверном сценарии.
  5. Создание PDF не заменяет редактирование существующего PDF, OCR, ручные аннотации или визуальную правку страниц.

Кому подойдёт

  1. Командам, которые уже формируют документы в HTML или могут перейти на шаблоны HTML/CSS.
  2. Python-разработчикам, которым нужна генерация PDF внутри приложения без ручного экспорта.
  3. Проектам с повторяемыми отчётами, актами, счетами, билетами, сертификатами, книгами и печатными формами.
  4. Тем, кому важны колонтитулы, пагинация, нумерация, закладки и воспроизводимый выпуск по одним правилам.

WeasyPrint не стоит выбирать как замену Acrobat-подобному редактору. Он создаёт документ из разметки, но не предназначен для ручной правки текста и объектов в уже готовом PDF. Не лучший это вариант и для страниц, внешний вид которых формируется сложным JavaScript после загрузки. В таких случаях сначала нужен другой этап подготовки статического HTML или иной движок.

Альтернативы и итоговые рекомендации

Когда выбирать Paged.js CLI, Vivliostyle CLI, iText или IronPDF

WeasyPrint — Python-ориентированный HTML/CSS-рендерер; альтернативы делают акцент на других средах и конвейерах

Ближайшие альтернативы выбирают не по абстрактному качеству, а по архитектуре проекта. Paged.js CLI логичен, когда команда строит печатную вёрстку вокруг JavaScript-экосистемы и Paged Media в Chromium-подобном окружении. Vivliostyle CLI ориентирован на публикации из HTML и Markdown и часто интересен для книг и технических материалов. Для приложений, где PDF является самостоятельной программной моделью, а не только печатным представлением HTML, полезнее смотреть в сторону SDK вроде iText Suite или IronPDF.

Практический выбор WeasyPrint оправдан, когда у проекта три условия: исходное содержимое можно выразить статическим HTML, оформление удобно держать в CSS, а выпуск должен быть автоматическим и воспроизводимым. В этом сценарии инструмент даёт короткий путь от данных к PDF и не заставляет строить собственный движок пагинации.

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

Для production закрепите версию WeasyPrint и системные зависимости, храните шрифты и критичные изображения контролируемо и проверяйте предельные данные. Обновления оценивайте по changelog: версия 70.0 содержит исправления безопасности. Генератор документов относится к инфраструктуре приложения, поэтому его обновляют и тестируют так же дисциплинированно, как серверный код.

1 / 5