PrinceXML Server превращает HTML и XML в PDF-документы с точной разбивкой на страницы, колонтитулами, сносками, оглавлением, закладками, встроенными шрифтами и профилями для архивации, доступности или полиграфии. Пользователь задаёт структуру документа разметкой, оформляет её CSS, при необходимости подключает JavaScript, а затем запускает преобразование из графического окна, командной строки или серверного кода.
В графическом окне исходные документы добавляются в левую таблицу, стили и сценарии — в панели справа, после чего порядок файлов можно изменить стрелками и запустить сборку кнопкой Convert. Для автоматизации те же параметры передаются команде prince: входом служит файл, набор файлов, адрес страницы или стандартный поток, а результат записывается в указанный PDF либо возвращается вызывающему процессу через стандартный вывод.
Типовой серверный процесс начинается не с ручного редактирования PDF, а с шаблона HTML: приложение подставляет данные заказа, отчёта или публикации, Prince загружает связанные таблицы стилей, изображения и шрифты, вычисляет страницы и возвращает неизменяемый результат. Такая схема удобна для счетов, персонализированных писем, каталогов, технической документации и книг, где один шаблон должен воспроизводимо обрабатывать тысячи разных наборов данных.
Скачать PrinceXML Server
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нет визуального редактора
- Нужны знания HTML и CSS
- Серверная лицензия платная
Как устроен рабочий процесс
PrinceXML Server получает уже подготовленное содержание и занимается именно версткой печатного результата. Он не хранит записи клиентов, не строит отчётные выборки и не заменяет шаблонизатор: эти задачи выполняет приложение, которое формирует HTML или XML. Движок читает структуру элементов, применяет каскад CSS, загружает ресурсы, рассчитывает переносы строк и страниц, после чего записывает PDF. Такое разделение полезно в поддерживаемом проекте: бизнес-логика остаётся в коде сайта или корпоративной системы, а правила печати сосредоточены в отдельных стилях.
Для первого теста достаточно файла с обычной HTML-разметкой. Если имя выходного файла не указано, команда создаёт PDF рядом с входным файлом; в производственном скрипте лучше всегда задавать путь явно, чтобы временные документы не смешивались с шаблонами. Несколько входных файлов можно объединить в один результат в порядке перечисления. При передаче страницы по HTTP или HTTPS движок загружает её так же, как остальные связанные ресурсы, однако итог определяется печатными стилями и поддерживаемыми возможностями, а не тем, как страница выглядит в конкретном браузере.
prince invoice.html -o invoice.pdf
prince cover.html chapter-01.html chapter-02.html -o book.pdf
prince -s print.css report.html -o report.pdf
В серверной задаче полезно заранее определить три каталога: неизменяемые шаблоны, временные данные конкретного задания и готовые результаты. Абсолютные пути снижают число ошибок, связанных с текущей рабочей директорией процесса. Отдельный файл стилей удобно передавать параметром, когда один и тот же HTML используется для разных вариантов: например, для электронного PDF, чёрно-белой печати и типографского макета с выпуском под обрез.
Графическое окно и его элементы
Верхняя левая панель содержит команды Add file(s), Add URL, Remove и Clear All. Добавленный документ появляется в таблице Documents с колонками имени, расположения, типа и состояния. Стрелки рядом с таблицей меняют порядок документов, что важно при сборке обложки, содержания и глав в единый файл. Флажок объединения позволяет направить несколько входов в один PDF, а поле сохранения задаёт итоговое имя. Нижняя таблица служит журналом: там появляются статус, расположение проблемного ресурса и сообщение движка.
Правая часть разделена на вкладки. На вкладке CSS & JavaScript находятся отдельные списки таблиц стилей и сценариев. Кнопки Add CSS и Add JS подключают файлы, Remove исключает выбранный элемент, Edit открывает ресурс для правки во внешнем редакторе. Порядок стилей имеет значение, потому что более поздние правила при одинаковой специфичности перекрывают ранние. Флажок Enable Document Scripts разрешает сценарии, уже встроенные в исходный документ; внешние файлы, добавленные как отдельные сценарии задания, следует контролировать независимо.
Вкладка PDF Settings предназначена для параметров результата, но основная сила программы раскрывается через CSS и командную строку, где доступны все ключи. Графическое окно удобно для проверки шаблона и обучения верстальщика: можно быстро заменить файл, посмотреть журнал и повторить преобразование. Для очереди запросов оно не подходит, потому что автоматизированный процесс должен получать код возврата, журнал и PDF без участия оператора.
Подготовка HTML и XML
HTML следует делать семантическим: заголовки оформлять элементами h1–h6, списки — ol и ul, таблицы — table с корректными строками и ячейками, иллюстрации — img с текстовым описанием. Такая структура облегчает создание закладок и тегированного PDF, а также делает шаблон предсказуемее при отключённых стилях. Не стоит собирать весь макет абсолютным позиционированием: оно удобно для отдельных наклеек или бланков, но ухудшает перенос длинного текста и делает страницу хрупкой при изменении данных.
При работе с XML документ должен быть корректным XML 1.0. Движок понимает пространства имён, DTD, символьные ссылки, CDATA, внутренние и внешние сущности. Возможности внешних сущностей и XInclude требуют осторожности: в задачах с непроверенными входами их лучше не включать, поскольку они способны обращаться к файлам и сетевым ресурсам. Для собственных XML-словарей оформление задаётся CSS-селекторами по элементам и атрибутам; универсальной браузерной таблицы стилей для произвольной схемы не существует.
Базовый адрес определяет, где искать относительные ссылки на стили, изображения, шрифты и другие документы. Для файла он обычно выводится из расположения входного файла, для данных из стандартного ввода его нужно задать явно, если шаблон содержит относительные пути. В XML не следует рассчитывать на xml:base: безопаснее передать базу параметром или преобразовать ссылки на этапе подготовки задания. При объединении нескольких источников каждый документ сохраняет собственный контекст загрузки ресурсов.
- Проверяйте закрытие тегов и кодировку до запуска движка.
- Указывайте язык документа для переноса слов и доступности.
- Храните печатные стили отдельно от экранных, если цели различаются.
- Не передавайте пользовательский HTML без очистки разрешённых элементов и атрибутов.
Каскад CSS и печатные стили
Prince учитывает встроенную таблицу стилей для типа документа, авторские правила из HTML и внешних файлов, а также пользовательские стили, переданные в задании. Конфликт разрешается по обычной специфичности селекторов и порядку подключения. Поэтому исправление, которое должно гарантированно перекрыть шаблон, лучше помещать в последний внешний файл, а не размножать правила с чрезмерным количеством идентификаторов и пометок important.
Медиавыражения позволяют отделить печатное оформление от экранного. Правила внутри media print применяются к PDF, а screen можно оставить для браузерного предпросмотра. При этом совпадение с браузером не является целью само по себе: печатный документ имеет конечный формат листа, поля, страницы слева и справа, области колонтитулов и правила разрыва. Для проверки полезно держать небольшой набор эталонных данных: короткое значение, максимально длинное имя, пустой блок, большая таблица и изображение на границе допустимого размера.
@media print {
body { font-family: "Noto Sans", sans-serif; font-size: 10pt; }
h2 { break-after: avoid; }
table { break-inside: auto; }
tr { break-inside: avoid; }
}
Свойства break-before, break-after и break-inside управляют разрывами, но они не могут отменить физическую невозможность разместить элемент. Если строка таблицы выше страницы, запрет разрыва не решит проблему; потребуется уменьшить содержимое, разрешить дробление или изменить структуру. Аналогично keep-подобные правила следует применять точечно: слишком много запретов заставляет верстальщик оставлять большие пустые области и переносить блоки дальше, чем ожидает автор.
Размер страницы, поля и именованные макеты
Правило @page задаёт формат листа, ориентацию и поля. Можно использовать стандартные ключевые размеры или точные единицы, включая миллиметры, сантиметры, пункты и дюймы. Для документов с разными форматами применяются именованные страницы: элемент получает свойство page, а соответствующее правило определяет отдельный размер и поля. Так обложка может быть без колонтитула, основная часть — на A4, а широкое приложение — в альбомной ориентации.
@page { size: A4; margin: 18mm 16mm 20mm; }
@page cover { margin: 0; }
.cover { page: cover; break-after: page; }
@page wide { size: A4 landscape; }
.wide-table { page: wide; }
Псевдоклассы left и right позволяют различать развороты: внутреннее поле делают шире под переплёт, номера размещают ближе к внешнему краю. first применяется к первой странице всего документа, а для групп страниц предусмотрены отдельные селекторы. Пустая страница, вставленная ради начала главы с нужной стороны, может иметь собственное оформление через blank. В длинной публикации это предотвращает появление случайных колонтитулов на технических пустых листах.
Метки реза, выпуск за обрез и область обрезки задаются печатными свойствами, когда PDF готовится для типографии. Эти параметры необходимо согласовывать с реальным заданием производства: добавление меток не создаёт содержимое за границей страницы автоматически. Фон и изображения должны действительно выходить в область bleed, иначе после резки останется белая полоса. Для офисного принтера такие настройки обычно не нужны и могут только уменьшить полезную площадь.
Колонтитулы, номера страниц и бегущие заголовки
Области страницы заполняются свойством content внутри @page. Номер берётся из счётчика page, общее число — из pages. Статический текст можно объединять со значениями атрибутов, строками и скопированными элементами. Для двустороннего макета часто создают два правила: на левой странице показывают название книги и номер слева, на правой — название текущей главы и номер справа.
@page:left {
@top-left { content: string(book-title); }
@bottom-left { content: counter(page); }
}
@page:right {
@top-right { content: string(chapter-title); }
@bottom-right { content: counter(page); }
}
h1.chapter { string-set: chapter-title content(); }
string-set копирует текст выбранного элемента в именованную строку. Это подходит для простого заголовка, но не переносит сложное оформление. Когда в колонтитуле нужны логотип, несколько строк или смешанные стили, применяют бегущий элемент через element() либо поток. Такой элемент можно повторять в области страницы, не дублируя разметку вручную. Следует помнить, что перенос элемента из основного потока меняет его обычное положение; для некоторых функций используется копирование, для других — изъятие.
Счётчики работают не только для страниц. Ими нумеруют главы, рисунки, таблицы, приложения и пункты договора. Вложенные счётчики позволяют получить номера вида 3.2.4. Сброс лучше привязывать к семантическому контейнеру главы, а не к визуальному классу, иначе перестановка блоков создаст неожиданные номера. Для вступительных страниц можно применить римский стиль, затем сбросить page перед основной частью и перейти к арабским цифрам.
Оглавление и перекрёстные ссылки
Оглавление удобно формировать из обычных ссылок на заголовки. Функция target-counter получает номер страницы, на которой расположен адресат, а leader заполняет расстояние точками. В результате номера пересчитываются при каждом изменении текста. Это принципиально надёжнее, чем записывать страницы в шаблон вручную: добавленная иллюстрация или перенос абзаца не потребует правки списка содержания.
.toc a::after {
content: leader(".") target-counter(attr(href), page);
}
.ref::after {
content: " на странице " target-counter(attr(href), page);
}
target-content может вывести текст целевого элемента, например название рисунка. Для сложной документации полезно хранить устойчивые идентификаторы, а ссылочный текст получать автоматически. Тогда переименование раздела меняется в одном месте. Если цель отсутствует, журнал должен считаться ошибкой сборки: незаметная пустая ссылка в сотнях документов хуже, чем остановленная задача. Для этого в автоматизации применяют fail-safe параметры, реагирующие на предупреждения или ошибки.
Закладки PDF являются отдельной навигационной структурой. Их уровень, подпись, состояние открытия и цель задаются CSS-свойствами bookmark-level, bookmark-label, bookmark-state и bookmark-target. Обычно заголовкам h1–h3 назначают уровни 1–3, но глубокие технические документы лучше ограничивать несколькими уровнями, иначе панель закладок становится громоздкой. Подпись можно брать из атрибута, если видимый заголовок содержит номер или декоративный текст, который не нужен в навигации.
Сноски, плавающие элементы и многоколоночная верстка
Сноска создаётся переводом элемента в специальный поток footnote. В основном тексте появляется вызов, а содержимое размещается в нижней области страницы. Маркер вызова и номер самой сноски оформляются отдельными псевдоэлементами. Такая схема сохраняет связь при переразбиении: если абзац переехал на следующую страницу, его сноска переносится вместе с ним. Очень длинная сноска всё равно может занять значительную часть листа, поэтому в шаблоне следует проверить предельные случаи.
Плавающие изображения могут обтекаться текстом слева или справа, переноситься наверх или вниз страницы, а в расширенных сценариях — откладываться на следующие страницы. Для подписи рисунок и caption лучше объединять в один контейнер, чтобы они не разрывались независимо. Page floats полезны в журнальной верстке, однако большое число конкурирующих плавающих блоков способно изменить порядок визуального появления. В научном тексте нужно решить, важнее ли точная близость к ссылке или компактное заполнение полосы.
Многоколоночная разметка создаётся свойствами column-count или column-width, расстояние регулирует column-gap. Балансировка распределяет текст между колонками, но таблица или непрерывный код могут оказаться слишком широкими. Для таких блоков используют column-span либо переход на именованную страницу. Не следует уменьшать шрифт до нечитаемого размера только ради сохранения числа колонок; лучше ослабить макет на конкретном элементе.
Таблицы и длинные наборы данных
HTML-таблица сохраняет привычную модель строк, ячеек, объединений и заголовочных групп. Элементы thead и tfoot могут повторяться на каждой странице, что особенно важно для счетов и реестров. Ширины вычисляются автоматически либо по фиксированному алгоритму table-layout: fixed. Автоматический режим учитывает содержимое и удобен для непредсказуемых данных, фиксированный даёт стабильную геометрию и быстрее объясняется дизайнеру, но требует заранее разумно распределить ширину столбцов.
Перенос строки контролируется break-inside, а заголовок таблицы должен быть достаточно коротким, чтобы поместиться вместе хотя бы с одной строкой данных. Если одна ячейка содержит длинный непрерывный адрес, артикул или код, добавьте разрешённые точки разрыва через overflow-wrap, word-break или обработку исходного значения. Нельзя рассчитывать, что движок аккуратно сократит данные сам: он верстает полученный текст и сообщает о переполнении, но не принимает бизнес-решение, какую часть удалить.
Для итоговых строк можно использовать счётчики и сгенерированное содержимое, однако арифметические суммы над бизнес-данными лучше вычислять до верстки. JavaScript способен модифицировать DOM, но расчёт налогов и валютных итогов должен оставаться в проверяемом коде приложения. Prince отвечает за представление числа, выравнивание и перенос, а не за истинность исходной суммы. Такой подход упрощает тестирование: один и тот же JSON должен давать одинаковые значения во всех каналах, включая PDF.
Шрифты, языки и переносы
Шрифты могут браться из системы или подключаться правилом @font-face по локальному файлу. Для серверной установки предпочтительнее хранить одобренные файлы рядом с шаблоном и явно задавать семейства: это уменьшает различия между тестовой и производственной машиной. Лицензия самого шрифта должна разрешать встраивание в PDF. Если в файле запрещено embedding, результат может отличаться или сборка профиля PDF/A завершится ошибкой, поскольку профиль PDF/A требует встроенных шрифтов.
Подмножество шрифта уменьшает размер PDF, оставляя только использованные глифы. Полное встраивание полезно, когда документ будет редактироваться внешним инструментом, но увеличивает файл и не всегда разрешено лицензией. Искусственные жирное и курсивное начертания лучше отключать в строгом издательском процессе и подключать реальные файлы начертаний. Для переменных OpenType-шрифтов следует проверить выбранные оси на эталонном документе, особенно если типография использует отдельный preflight.
Переносы зависят от языка и словаря. Атрибут lang на html или конкретном фрагменте сообщает, какой набор правил применять. Для русского текста нужно не только выбрать кириллический шрифт, но и обозначить русский язык; иностранные цитаты можно пометить отдельно. Свойство hyphens управляет автоматическим переносом, а мягкий перенос позволяет указать предпочтительную точку вручную. В идентификаторах, адресах и кодах автоматические переносы часто отключают, чтобы не создавать двусмысленность.
Сообщение no font for character означает, что ни одно доступное семейство не содержит нужного глифа. Исправление состоит не в подавлении предупреждения, а в подключении подходящего шрифта и проверке цепочки fallback. Ошибка no available fonts указывает на более фундаментальную проблему установки или конфигурации Fontconfig. В контейнере набор шрифтов необходимо включать в образ явно; наличие шрифта на рабочем ноутбуке разработчика ничего не гарантирует на сервере.
Изображения, SVG и математические формулы
В разметку можно включать JPEG, PNG, TIFF, GIF, WebP, AVIF и SVG. Для фотографий обычно подходит JPEG или WebP с контролируемым качеством, для схем — SVG, для изображений с прозрачностью и резкими границами — PNG. Размер на странице определяется CSS, а не только числом пикселей. Если у файла нет корректной информации о разрешении, физический размер можно задать шириной и высотой либо свойствами разрешения изображения.
SVG сохраняет векторные контуры и удобен для диаграмм, иконок и логотипов. Внешние ресурсы внутри SVG подчиняются тем же сетевым и файловым ограничениям, что HTML. Фильтры могут привести к растеризации части изображения; качество регулируется разрешением фильтра. Если тень или эффект выглядит размыто при увеличении, следует поднять prince-filter-resolution только для нужного документа, понимая, что это увеличит время и объём памяти.
MathML интегрируется в HTML и преобразуется в графическое представление формулы. Качество зависит от математических шрифтов и структуры разметки. Снимок формулы в PNG проще, но теряет масштабируемость и семантику; MathML лучше для научных публикаций и доступности. Сложные библиотеки, рассчитанные на современный браузерный DOM, могут не запуститься из-за ограничений JavaScript, поэтому предпочтительнее передавать уже сформированный MathML или использовать совместимый сценарий.
Свойства image-magic позволяют перекодировать изображения и уменьшать PDF, например пересжимать JPEG или преобразовать PNG в JPEG. Это следует применять к подходящему типу контента: конвертация схемы с прозрачностью в JPEG создаст фон и артефакты. Для мастер-копии лучше сохранить исходники, а оптимизацию выполнять в отдельном профиле выпуска. Растровый вывод страниц в PNG или JPEG пригоден для миниатюр и предварительного просмотра, но не заменяет основной PDF.
Цвет, ICC-профили и подготовка к печати
Для офисных документов обычно достаточно RGB, а полиграфический процесс требует согласованного цветового пространства и output intent. Prince умеет работать с ICC-профилями, выполнять преобразование цвета и формировать PDF/X при соблюдении ограничений выбранного профиля. Профиль нельзя выбирать по названию наугад: типография должна сообщить требуемый стандарт, профиль печатного процесса, допустимость прозрачности и выпуск за обрез.
True black и rich black решают разные задачи. Чистый чёрный канал удобен для мелкого текста и штрихкодов, поскольку не требует совмещения нескольких красок. Составной чёрный делает большие плашки визуально плотнее, но формула зависит от производства. Автоматическое превращение всего чёрного текста в многокрасочный способно ухудшить резкость. Настройку цвета следует проверить в preflight и на пробном оттиске.
PDF/A требует независимого от устройства описания цвета, встроенных шрифтов и запрещает шифрование. PDF/X также требует output intent и ограничивает функции, несовместимые с надёжным обменом в полиграфии. Если документ не проходит профиль, правильная реакция — исправить ресурс или параметр, а не отключить проверку. Например, отсутствие профиля или неподдерживаемая прозрачность означает, что файл ещё не соответствует заявленной цели.
Закладки, метаданные и поведение PDF
Название документа берётся из title, а автор, тема, ключевые слова и даты могут задаваться метаданными HTML либо параметрами задания. Дополнительный XMP-пакет подключается отдельным файлом. Метаданные полезны для поиска и систем хранения, но не должны содержать секретные значения, оставшиеся от шаблона. Перед выпуском проверьте, что название и автор относятся к конкретному документу, а не к демонстрационному примеру.
Панель закладок, стартовый масштаб, режим одной или двух страниц и отображение вложений задаются свойствами PDF. Это пожелания для просмотрщика, а не абсолютная команда: разные программы могут игнорировать часть настроек. То же относится к PDF-скриптам, например автоматическому открытию диалога печати. Они особенно зависят от Adobe Acrobat и могут быть заблокированы политикой безопасности, поэтому критический рабочий процесс не должен основываться только на таком действии.
Ссылки внутри документа превращаются в переходы по PDF. Внешние ссылки сохраняются как веб-адреса, если это разрешено выбранным профилем. Относительную ссылку можно трактовать как файловую или сетевую в зависимости от базы и настроек. В публичном отчёте стоит проверить, что тестовые адреса и локальные пути не попали в результат. Для PDF/X-4 ссылки ограничены требованиями профиля, а в профилях PDF/A вложения поддерживаются не одинаково.
Сжатие, вложения и защита
Сжатие потоков и объектные потоки уменьшают размер результата, особенно у тегированных документов. Подмножество шрифтов и рациональная обработка изображений обычно дают больший эффект, чем попытка сжать уже сжатый JPEG. Если PDF неожиданно вырос, сначала найдите крупные растровые ресурсы, дублированные шрифты и страницы с растеризованными эффектами. Отключать сжатие имеет смысл только для диагностики или совместимости с особым инструментом.
К PDF можно прикреплять дополнительные файлы, однако доступность функции зависит от профиля. PDF/A-3 рассчитан на вложения, тогда как для других вариантов действуют ограничения; PDF/X-4 допускает вложения, но запрещает ссылки. В счёте это позволяет хранить исходный XML рядом с визуальным представлением, если регламент действительно требует такой контейнер. Имя, MIME-тип и назначение вложения должны быть понятны системам-получателям.
Шифрование поддерживает пароль пользователя и владельца, а также запреты печати, изменения, копирования и аннотаций. Эти флаги не являются полноценной системой управления правами: программа, игнорирующая ограничения, может обработать открытый документ. Для конфиденциальных данных важнее защищённый канал доставки и контроль доступа к файлу. Архивные и типографские профили запрещают шифрование, поэтому одновременно заявить PDF/A и закрыть его паролем нельзя.
Тегированный PDF и доступность
Тегированный PDF хранит логическую структуру, необходимую программам чтения с экрана и корректному извлечению текста. Семантический HTML даёт хорошую основу: заголовки, списки, таблицы и подписи превращаются в соответствующие элементы структуры. Для собственного XML тип тега можно назначить CSS-свойствами и сопоставить нестандартные роли со стандартными. Автоматическая генерация не освобождает от проверки порядка чтения и текстовых альтернатив.
Профиль PDF/UA-1 требует логичных тегов, встроенных шрифтов, Unicode-сопоставления и доступности содержимого для вспомогательных технологий. Значимые изображения должны иметь alt, декоративные — быть исключены из смыслового дерева. Таблицам нужны заголовочные ячейки и понятные связи. Цветовой контраст и ясность текста остаются обязанностью автора CSS; движок не может определить, понятна ли формулировка или достаточно ли информативна подпись.
После сборки файл следует проверять специализированным валидатором и вручную в программе чтения с экрана. Формальное прохождение профиля не гарантирует удобство: неправильный порядок элементов, повторяющийся декоративный текст или неудачные подписи могут остаться. Для массового выпуска полезно включить автоматический валидатор в конвейер и хранить отчёт рядом с артефактом, а выборочно проводить ручное тестирование шаблонов.
Интерактивные формы
HTML-элементы формы можно превратить в поля PDF командой --pdf-forms. Поддерживаются распространённые текстовые поля, переключатели, флажки, списки, а также кнопки отправки и сброса, хотя поведение последних зависит от просмотрщика. CSS-свойство -prince-pdf-form позволяет включить или отключить отдельный элемент, если не вся форма должна оставаться интерактивной. Для текстовых полей предусмотрен автоматический размер шрифта, чтобы введённое значение помещалось в границы.
prince --pdf-forms application.html -o application.pdf
input, select, textarea {
-prince-pdf-form: enable;
}
input.long-value {
-prince-pdf-form-field-font-size: auto;
}
Внешний вид обычного HTML-контрола и интерактивного поля PDF может различаться. Проверяйте результат как минимум в двух просмотрщиках, потому что поддержка кнопок, сценариев и сохранения данных неодинакова. Для доступной формы нужны подписи, порядок табуляции и профиль PDF/UA. Поле подписи создаётся специальным типом, но само наличие поля не подписывает документ: криптографическую подпись накладывает пользователь или отдельная система.
Если значения должны быть неизменяемыми, не включайте режим формы: отрисуйте данные как обычный текст. Смешанный документ может содержать заполненные сервером поля и зоны, оставленные пользователю, но следует ясно различать их оформлением. Перед отправкой заполненной формы во внешнюю систему уточните, поддерживает ли просмотрщик нужное действие; универсальнее сохранить PDF и загрузить его через отдельный интерфейс.
JavaScript до и после верстки
Сценарии могут строить оглавление, сортировать таблицу, создавать диаграмму, добавлять индексы и менять DOM перед расчётом страниц. Встроенный JavaScript не запускается автоматически: его нужно разрешить параметром --javascript или соответствующей настройкой задания. Внешний сценарий подключается отдельным ключом. Это разделение важно для безопасности, поскольку документ, полученный от пользователя, не должен незаметно выполнять код.
Поддерживается большая часть ECMAScript 5, ряд возможностей ES6, но полная совместимость с современным браузером отсутствует. Строгий режим и поздние стандарты не следует считать доступными. Библиотеки, зависящие от class, модулей, полного classList, dataset или сложной браузерной среды, могут потребовать транспиляции и адаптера. Для серверного шаблона надёжнее небольшой контролируемый сценарий, чем большой фронтенд-пакет.
Первый проход JavaScript выполняется до верстки и может менять документ. После расчёта доступна инспекция геометрии; зарегистрированная post-layout функция способна инициировать дополнительный проход, если изменит DOM. Это полезно для задач, зависящих от фактических страниц, но каждый проход увеличивает время. Устанавливайте максимальное число проходов и следите, чтобы условие сходилось, иначе шаблон будет пересобираться без полезного результата.
События мыши и клики внутри печатного документа не работают как на веб-странице. Отдельно существуют сценарии, вложенные в сам PDF, которые выполняются просмотрщиком при открытии, сохранении или печати. Их совместимость ограничена и зависит от политики безопасности. Не переносите серверную логику в PDF-скрипт: он подходит для необязательного удобства, но не для вычисления обязательных данных.
Вызов из серверного кода
Самый универсальный способ — запустить команду как дочерний процесс. Приложение передаёт аргументы массивом, пишет HTML в стандартный ввод и читает PDF из стандартного вывода. Аргументы нельзя собирать строковой конкатенацией из пользовательских значений: это создаёт риск командной инъекции. Пути и параметры должны передаваться отдельными элементами, а имена временных файлов — генерироваться сервером.
p = subprocess.Popen(
["prince", "-", "-o", "-"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
pdf, log = p.communicate(html_bytes)
if p.returncode != 0:
raise RuntimeError(log.decode("utf-8", errors="replace"))
Официальные обёртки предусмотрены для Java, .NET и PHP; из Python, Perl и других языков удобно работать через процесс и потоки. Обёртка обычно позволяет добавить стили, сценарии, журнал, профиль и выполнить преобразование одного или нескольких файлов. Она не отменяет необходимость установить исполняемый файл Prince и указать его путь. При обновлении проверяйте совместимость версии обёртки и движка на тестовом наборе.
Когда запрос возвращает PDF браузеру, заголовок Content-Type должен быть application/pdf, а имя файла — безопасно закодировано. Не отправляйте заголовки до успешного завершения, если инфраструктура позволяет сначала получить результат во временный буфер: иначе клиент может получить частичный PDF с кодом 200. Для больших документов буфер в памяти заменяют временным файлом или потоковой схемой с контролем ошибок.
JSON-задания и управляющий протокол
Prince Job описывает вход, параметры PDF и метаданные в JSON. Объект input содержит src, тип, базовый адрес, media, список стилей и сценариев, разрешение JavaScript, XInclude, внешних сущностей и iframe. Объект pdf управляет шрифтами, сжатием, цветом, шифрованием, профилем, XMP, тегами, вложениями и PDF-скриптами. Такая форма удобнее длинной командной строки, когда параметров много и они формируются программно.
Control Protocol — двунаправленный синхронный протокол через стандартные потоки. Процесс Prince остаётся запущенным и принимает последовательность заданий, что уменьшает стоимость частого старта и позволяет приложению отделить очередь от движка. Каждое сообщение имеет структурированные части, включая ресурсы задания и результат. Реализация должна строго соблюдать границы сообщений и обрабатывать состояние процесса после ошибки.
Для одного редкого документа обычный запуск проще и прозрачнее. Управляющий режим оправдан при постоянной нагрузке, когда измерения показывают заметную долю времени на инициализацию. Не следует сразу создавать большой пул процессов: сначала определите средний размер документов, потребление памяти и реальную параллельность. Ограниченная очередь защищает сервер лучше, чем неограниченное создание процессов при всплеске запросов.
Журналы, коды возврата и fail-safe правила
В командной строке предупреждения и ошибки выводятся в stderr. Параметр verbose добавляет сведения о загрузке и ходе обработки, log записывает сообщения в файл. Структурированный журнал предназначен для машинной обработки: приложение может получить тип сообщения, место и категорию без разбора человеческой строки. В рабочем конвейере сохраняйте идентификатор задания, время, код возврата, версию шаблона и сокращённый журнал.
Не всякое предупреждение допустимо. Отсутствующий шрифт, незагруженное изображение, недействительная ссылка или нарушение профиля могут оставить формально созданный PDF, который нельзя отправлять клиенту. Fail-safe параметры позволяют считать выбранные условия фатальными и не создавать результат. Набор строгих правил лучше вводить постепенно на эталонных документах, чтобы не остановить выпуск из-за безвредного диагностического сообщения.
Код возврата проверяется всегда. Наличие файла ещё не означает успех: предыдущий PDF мог остаться по тому же пути. Перед задачей используйте уникальное имя или удаляйте старый результат, после — проверяйте код, размер и сигнатуру PDF. Для критических документов дополнительно запускайте валидатор профиля и проверку числа страниц. Итог перемещают в постоянное хранилище только после всех проверок.
Capture и Replay для воспроизводимых ошибок
Пара --capture и --replay сохраняет полное окружение задания: входные документы и ресурсы, на которые они ссылаются, включая удалённые стили, изображения, сценарии и шрифты. Захваченный каталог можно воспроизвести позже без зависимости от изменившегося сайта. Это особенно полезно, когда ошибка возникает только на одном наборе данных или внешний ресурс успевает обновиться до начала расследования.
Каталог захвата способен содержать персональные данные, закрытые URL, шрифты и коммерческие изображения. Его нельзя автоматически прикладывать к публичному тикету. Перед передачей поддержке проверьте содержимое, удалите секреты либо создайте минимальный обезличенный пример. Права на файлы должны соответствовать политике организации, а срок хранения — быть ограничен.
Replay помогает отделить проблему движка от шаблонизатора и сети. Если захваченное задание повторяет дефект, разработчик работает с фиксированным набором. Если нет, следует искать различия окружения: переменные, права, доступные шрифты, библиотеку SSL, лимит памяти или рабочую директорию. Минимизация примера остаётся важной: небольшой документ быстрее проверяется и яснее показывает условие ошибки.
Безопасная обработка непроверенных данных
HTML, XML, CSS, SVG и JavaScript являются активными форматами: ссылки способны читать локальные файлы и обращаться к сети, внешние сущности — раскрывать содержимое, iframe — загружать страницы, а сценарии — выполнять поддерживаемые операции DOM и запросы. Первой линией защиты служит очистка данных по белому списку. Простое удаление тега script недостаточно, потому что опасный адрес может находиться в стиле, изображении, SVG или XML.
Параметр --no-local-files запрещает доступ к локальной файловой системе, --no-network — сетевые загрузки. Их следует включать для пользовательского контента и передавать необходимые ресурсы как явно разрешённые данные задания. XInclude, внешние XML-сущности и iframe по умолчанию не нужны большинству шаблонов; не включайте их без конкретной причины. Процесс запускают от отдельного пользователя с минимальными правами.
Контейнер или песочница дополняют настройки движка. Ограничьте CPU, память, число процессов, время выполнения и размер входа. Длинная строка, огромный SVG, многокадровый GIF или рекурсивная структура могут потребовать значительно больше ресурсов, чем размер файла на диске. Тайм-аут должен завершать всю группу процесса, чтобы дочерний движок не остался работать после отмены запроса.
Секреты не следует помещать в URL ресурсов, потому что адрес может оказаться в журнале и capture-каталоге. Для доступа к защищённым данным приложение должно заранее получить ресурс, проверить его и передать локальную копию либо содержимое. Сертификаты HTTPS и цепочки доверия в контейнере нужно поддерживать отдельно. Ошибка TLS не исправляется отключением проверки сертификата на производстве.
Развёртывание на Windows, Linux, macOS и в контейнере
На Windows устанавливается MSI либо распаковывается ZIP; командный исполняемый файл находится в каталоге enginein, а графическое окно запускается отдельно. Для служб лучше указывать полный путь к prince.exe, потому что системная переменная PATH у сервисной учётной записи отличается от интерактивной. Папка ресурсов содержит словари переносов, DTD, сертификаты, ICC-профили, стили, математические ресурсы и файл лицензии; копировать только один exe недостаточно.
Для Debian и Ubuntu доступны пакеты deb, для AlmaLinux и openSUSE — rpm, для Alpine — apk, также существуют tar.gz для конкретных систем и универсальных Linux-сред. Пакет подбирают по дистрибутиву и архитектуре. Generic Linux помогает, когда штатного пакета нет, но может потребовать совместимых общих библиотек. Сообщение error while loading shared libraries означает, что загрузчик не нашёл зависимость или её версию.
Сборка для macOS распространяется как универсальный ZIP-пакет. В облаке используются обычные виртуальные машины, контейнеры, Azure, EC2 или специально подготовленный пакет для AWS Lambda. Официальный Docker-образ упрощает начало, однако производственный образ должен закреплять тег, включать шрифты и лицензию безопасным способом. Монтирование license.dat предпочтительнее копирования секрета в публичный слой образа.
При обновлении сначала собирают новый образ или узел параллельно, прогоняют регрессионный набор и сравнивают PDF визуально и структурно. Изменения CSS-поддержки могут быть корректными по стандарту, но изменить старую верстку. Переключение трафика выполняют после проверки, а предыдущую среду сохраняют на время отката. Не заменяйте бинарный файл внутри работающего контейнера вручную.
Установка и файл лицензии
Установщик Windows последовательно показывает предупреждение запуска, приветствие, лицензионное соглашение, каталог назначения и завершение. В корпоративном развёртывании пакет можно распространять средствами управления устройствами, но параметры тихой установки следует проверять на выбранном MSI, а не переносить из старой инструкции. После установки команда prince --version подтверждает доступность движка, а prince --show-license — состояние лицензии.
После подтверждения безопасности мастер показывает начальный экран и предлагает перейти к условиям использования. На этом этапе полезно проверить имя продукта и издателя, особенно если пакет был передан через внутреннее хранилище, а не скачан непосредственно с сайта разработчика.
Лицензионное соглашение нужно принять до выбора каталога. Для автоматизированного развёртывания юридические условия и допустимый серверный сценарий согласуют заранее; технический флаг тихой установки сам по себе не предоставляет права использовать движок в производственном сервисе.
Лицензионный файл на Windows принимается через окно License: кнопка Open выбирает license.dat, затем Accept устанавливает его. На Unix-подобных системах файл копируется в каталог license внутри ресурсов Prince. Сервисная учётная запись должна иметь право чтения, но не обязательно изменения. Ошибка с сохранением водяного знака часто связана с неправильным путём, правами или лицензией, которая не применяется к установленному выпуску.
Для автоматической генерации документов условия использования отличаются от интерактивной работы одного человека. До ввода в эксплуатацию нужно выбрать лицензию, разрешающую серверный сценарий и характер выпуска документов. Бесплатный режим подходит для оценки и разрешённых некоммерческих задач, но добавляет идентифицирующую отметку. Лицензия не меняет алгоритм верстки и не должна использоваться как способ скрыть различия тестовой среды.
Завершающий экран мастера означает, что файлы скопированы, но не подтверждает работоспособность серверной учётной записи. После закрытия мастера выполните тестовую конверсию из того же окружения, где будет работать служба, и проверьте журнал, выходной PDF и отсутствие оценочного водяного знака.
Производительность и параллельная обработка
Время зависит от числа страниц, сложности CSS, количества шрифтов, объёма изображений, JavaScript и сетевых загрузок. Размер HTML сам по себе плохо предсказывает нагрузку: небольшая таблица со сложным перерасчётом или SVG-фильтром может быть тяжелее большого линейного текста. Измеряйте реальные шаблоны, отдельно фиксируя подготовку данных, загрузку ресурсов, верстку и запись файла.
Параллельность ограничивают ресурсами узла. Несколько процессов обычно обрабатывают независимые задания, но сотня одновременных конверсий может исчерпать память и ухудшить время каждого запроса. Очередь с фиксированным числом работников даёт предсказуемость и обратное давление. Количество работников подбирают нагрузочным тестом, учитывая худший документ, а не только средний.
Сетевые ресурсы добавляют задержку и нестабильность. Для массовых счетов лучше хранить стили, логотипы и шрифты локально в версии шаблона. Изображения клиентов можно загрузить и проверить до запуска. Кэш внешних страниц должен учитывать актуальность и права доступа. Повторное использование управляющего процесса снижает накладные расходы, но требует мониторинга его памяти и перезапуска по контролируемой политике.
Прогресс больших документов можно собирать из журнала, но клиенту обычно достаточно состояния очереди: ожидает, обрабатывается, завершено или ошибка. Отмена должна завершать задачу и удалять временные файлы. Метрики включают длительность, число страниц, размер PDF, код завершения, категорию предупреждений и пиковое потребление ресурсов. Без таких данных трудно отличить медленный шаблон от перегруженного сервера.
Диагностика типовых ошибок
Не найден шрифт или символ заменён вопросительным знаком
Проверьте, установлен ли нужный файл, содержит ли он символ и доступен ли пользователю сервиса. В контейнере обновите кэш Fontconfig и убедитесь, что @font-face указывает на существующий путь. Добавьте явную цепочку fallback для кириллицы, математических знаков и эмодзи. Не используйте картинку вместо текста, если документ должен быть доступным и индексируемым.
Изображение не загружается
Журнал покажет адрес и причину. Относительный путь может вычисляться от другой базы, сетевой запрос — блокироваться параметром no-network, локальный файл — no-local-files. BMP не относится к поддерживаемым форматам, поэтому его нужно преобразовать, например, в PNG. Для HTTPS проверьте сертификат и CA bundle. Пустой alt не исправляет отсутствующий файл, он лишь описывает роль изображения.
Команда не найдена или отсутствует общая библиотека
Для command not found добавьте каталог bin в PATH сервиса либо используйте абсолютный путь. Ошибка загрузчика с libtiff, libxml или другой библиотекой означает несовместимый пакет или неполные зависимости; установите пакет для своего дистрибутива, а не случайный tar.gz. LD_LIBRARY_PATH применяйте осознанно, чтобы не подменить библиотеки всего процесса.
Страница отличается от браузера
Убедитесь, что применяется media print, загружены те же шрифты и нет браузерной функции, которую движок не поддерживает. CSS Grid ограничен версткой в пределах одной страницы и не фрагментируется, современные JavaScript-библиотеки могут требовать неподдерживаемого DOM. Перепишите печатный макет под paged media вместо попытки буквально снять экранную страницу.
PDF создан, но профиль не проходит проверку
Читайте первое сообщение о нарушении, а не только итог. Для PDF/A часто виноваты невстроенный шрифт, неверный цвет или шифрование; для PDF/X — отсутствие output intent или запрещённая функция; для PDF/UA — теги, язык и альтернативы. Исправьте входные данные, затем прогоните независимый валидатор. Переименование файла в pdfa не меняет его соответствие.
Практический шаблон для счёта или акта
Приложение формирует HTML из проверенных данных: номер, дата, реквизиты, строки товаров, налоги и итог. В head подключаются локальный CSS и метаданные, на html задаётся язык. Шапка документа оформляется обычной таблицей или grid только там, где блок не должен переходить на другую страницу. Таблица позиций использует thead для повторяемого заголовка, а итоговый блок — запрет разрыва и отступ сверху.
В @page задаются A4, поля и нижний колонтитул с номером страницы. Логотип хранится в контролируемом формате SVG или PNG. Шрифты подключаются локально, чтобы реквизиты одинаково отображались на всех узлах. Длинные наименования разрешают переносить, а артикулы получают правила для аккуратного разрыва. Строки суммы вычисляет приложение, PDF лишь представляет их.
Запуск выполняется с запретом сети, если все ресурсы уже локальны. Журнал сохраняется вместе с идентификатором заказа, предупреждения о шрифтах и ресурсах считаются ошибкой. После конверсии проверяются сигнатура, минимальный размер и ожидаемое число страниц. Если нужен документ PDF/A, включается PDF/A и валидатор. Только затем файл получает постоянное имя и становится доступен клиенту.
Практический шаблон для книги и технического руководства
Материал разделяют на главы с устойчивыми идентификаторами. Счётчики создают нумерацию заголовков, рисунков и таблиц; оглавление получает номера через target-counter. Именованные строки передают название главы в верхний колонтитул, а left/right различают развороты. Перед каждой главой задаётся разрыв на правую страницу, пустые листы получают отдельное правило без лишнего текста.
Сноски оформляются потоком footnote, код — моноширинным шрифтом с разрешённым переносом, широкие таблицы переводятся на альбомную именованную страницу. Закладки повторяют только основные уровни. Для печати добавляют выпуск и метки по требованиям типографии, для электронной версии — активные ссылки и меньший размер изображений. Из одного HTML можно получать несколько вариантов, подключая разные финальные CSS.
Регрессионный набор должен включать главу с большим количеством сносок, длинное оглавление, рисунок у конца страницы, таблицу на несколько листов, разные письменности и формулу. Сравнение по изображениям страниц помогает заметить сдвиг верстки, а структурная проверка — изменение закладок, метаданных и тегов. Одной проверки первых двух страниц недостаточно.
Практический шаблон для доступного отчёта
Исходный HTML строится в логическом порядке чтения, даже если CSS визуально переставляет отдельные блоки. Заголовки не пропускают уровни без причины, таблицы имеют caption и th, изображения — содержательный alt, язык документа и фрагментов задан явно. Декоративные линии и фон не попадают в смысловую структуру. Цвет не используется как единственный способ передать статус.
Включается тегированный PDF или профиль PDF/UA-1, все шрифты встраиваются. Для нестандартных XML-элементов назначаются роли и карта ролей. Формы получают подписи и понятные имена. После создания запускается валидатор, затем документ читается клавиатурой и программой экранного доступа. Особое внимание уделяется порядку таблиц, сносок, колонтитулов и повторяемых элементов.
Ошибки доступности исправляют в шаблоне, а не постобработкой каждого PDF. Если один декоративный элемент неправильно тегируется во всех отчётах, изменение CSS устраняет проблему сразу для будущих выпусков. Существующие документы могут потребовать пересборки. Версия шаблона и результат проверки должны храниться для аудита.
Ограничения, которые важно учитывать
PrinceXML Server не предназначен для редактирования существующего PDF. Он не перемещает вручную текстовые блоки на существующей странице, не исправляет скан, не объединяет произвольные PDF как редактор и не распознаёт текст. Если исходником служит уже созданный PDF, для правки потребуется другой инструмент. Сильная сторона Prince — воспроизводимое создание нового документа из структурированных данных.
Встроенного визуального конструктора шаблонов нет. Графическое окно управляет входными файлами, стилями, сценариями и параметрами, но сам макет создаётся в HTML и CSS. Предпросмотр открывается во внешнем PDF-просмотрщике; автоматическое обновление можно организовать скриптом или средой разработки. Пользователю без навыков веб-верстки потребуется готовый шаблон и понятная форма данных.
Совместимость с CSS и JavaScript ориентирована на печатные документы, а не на полное повторение текущего Chromium. Grid не фрагментируется между страницами, часть современных селекторов, DOM API и стандартов отсутствует либо реализована частично. Перед переносом существующего сайта оцените его зависимости. Часто быстрее создать отдельный print.css и упростить интерактивные компоненты, чем адаптировать весь фронтенд-пакет.
Серверное применение требует подходящей лицензии. Бесплатный режим имеет условия использования и добавляет отметку, а лицензия для одного интерактивного пользователя не разрешает автоматическую выдачу из веб-приложения. До проектирования коммерческой услуги уточните разрешённый сценарий, количество производственных узлов и использование документов внешними получателями.
Сравнение PrinceXML Server с аналогами
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| PrinceXML Server | Сложной HTML/CSS-верстки, книг, отчётов, PDF/A, PDF/X и PDF/UA | Нет визуального конструктора шаблонов |
| Antenna House Formatter | Корпоративной XML-публикации, XSL-FO, DITA и многоязычной полиграфии | Сложная коммерческая система |
| WeasyPrint | Открытых Python-проектов, счетов и отчётов на HTML/CSS | Не повторяет весь браузерный стек |
| Vivliostyle CLI | Книг и публикаций из HTML или Markdown с открытым кодом | Зависит от Node.js и браузерного движка |
| wkhtmltopdf | Старых проектов, уже настроенных под Qt WebKit | Устаревший WebKit ограничивает CSS |
| DocRaptor | Облачного API с движком Prince без обслуживания серверов | Документы передаются внешнему сервису |
PrinceXML Server выбирают, когда нужен контролируемый собственный узел и сильная печатная верстка CSS. Antenna House Formatter уместен в организациях, где центральны XSL-FO, DITA и специализированные издательские стандарты. WeasyPrint подходит команде Python, которой важны открытая лицензия и умеренная сложность макетов. Vivliostyle удобен для открытого книжного конвейера из HTML или Markdown. wkhtmltopdf имеет смысл сохранять в уже работающей старой системе, но начинать на нём новый сложный макет рискованно. DocRaptor сокращает администрирование, если допустима передача данных облачному API.
Чек-лист перед вводом шаблона в эксплуатацию
- Сформируйте набор граничных данных: пустые поля, максимальные строки, большие таблицы, разные языки и изображения.
- Закрепите локальные шрифты, стили и графику в версии шаблона.
- Проверьте страницы, закладки, метаданные, ссылки и порядок чтения.
- Включите запрет локальных и сетевых ресурсов там, где они не нужны.
- Определите предупреждения, которые останавливают выпуск.
- Ограничьте время, память, размер входа и параллельность.
- Сохраняйте код возврата и структурированный журнал.
- Проверяйте профиль независимым валидатором, если он заявлен.
- Сравнивайте результат после обновления движка или шаблона.
- Подтвердите, что лицензия разрешает реальный сценарий выдачи документов.
Тест следует выполнять тем же способом, что и производство. Успешное нажатие Convert в интерактивном окне не гарантирует правильные пути, шрифты и права сервисной учётной записи. Разверните тестовый экземпляр с теми же ограничениями сети и файловой системы, отправьте через него эталонные задания и сохраните результаты для сравнения.
Как поддерживать шаблоны без ручной правки каждого PDF
Храните HTML, CSS, сценарии и тестовые данные в системе контроля версий. Изменение проходит рецензию как обычный код: проверяется семантика, влияние на страницы, доступность и безопасность ресурсов. Версию шаблона записывайте в метаданные или внутренний журнал задания, чтобы по выпущенному документу можно было восстановить использованные правила.
Разделяйте базовый стиль, компоненты и профиль выпуска. Базовый файл определяет шрифты и общую геометрию, компоненты — таблицы, предупреждения и подписи, финальный профиль — размер страницы, цвет и оптимизацию. Это уменьшает дублирование без превращения каскада в непонятную сеть импортов. Каждый слой должен иметь ясную ответственность.
Визуальные тесты строятся на рендеринге страниц в изображения и сравнении с допустимым порогом. Они замечают сдвиги, но дают ложные отличия при изменении сглаживания шрифтов, поэтому дополняются проверкой текста, числа страниц, закладок и тегов. Критические числовые значения сверяются с исходными данными. PDF нельзя считать основанием для расчёта.
Когда ошибка обнаружена в отправленном документе, исправьте шаблон, создайте новую версию и решите, какие файлы нужно перевыпустить. Ручная правка отдельного PDF скрывает причину и оставляет дефект в конвейере. Capture проблемного задания помогает воспроизвести старый результат, даже если внешние ресурсы уже изменились.
Базовый адрес, тип входа и загрузка связанных ресурсов
При обработке файла Prince вычисляет относительные ссылки от расположения исходного документа. Для данных, переданных через стандартный ввод или сформированных в памяти, естественной файловой базы нет, поэтому её следует задать явно. Базовый адрес определяет, где искать CSS, изображения, шрифты, вложенные документы и цели некоторых ссылок. Если забыть эту настройку, один и тот же HTML будет работать при ручном запуске из каталога шаблона и терять ресурсы внутри серверного процесса.
prince --baseurl=/srv/templates/invoice/ - -o result.pdf
prince --input=html generated.txt -o result.pdf
prince --input=xml data.xml -s report.css -o result.pdf
Режим входа можно определить автоматически либо указать как HTML или XML. Явный выбор полезен, когда расширение файла не отражает содержимое, данные приходят без имени или XML должен обрабатываться строго. HTML-парсер терпим к привычной веб-разметке, а XML требует корректной вложенности, закрытых элементов и экранирования специальных символов. Ошибка синтаксиса XML должна исправляться на этапе формирования данных, а не маскироваться стилями.
Адрес документа по HTTP становится базой для относительных ресурсов автоматически. При перенаправлениях и защищённых ресурсах нужно убедиться, что итоговые CSS и изображения доступны тому же процессу. Страница может открываться у оператора в браузере благодаря его cookie, но не загружаться на сервере без аутентификации. Надёжный конвейер передаёт разрешённые ресурсы самостоятельно или использует отдельный технический доступ с минимальными правами.
Медиа-режим влияет на выбор правил @media. Для печатного результата обычно используется print; попытка копировать экранный вид через screen часто переносит в PDF навигацию, интерактивные панели и скрывает элементы, предназначенные для бумаги. Лучше иметь общий набор компонентов и отдельный печатный слой. Значение media фиксируют в задании, чтобы изменение окружения не переключило оформление незаметно.
Загрузка внешнего ресурса должна отражаться в журнале. Для каждого шаблона полезен тест, в котором намеренно отсутствует картинка или шрифт: он показывает, остановит ли политика выпуска задачу или создаст неполный файл. Относительные пути, различие регистра имён в Linux и неверно закодированные пробелы относятся к самым частым причинам. Все пути проверяют в окружении сервисной учётной записи, а не только из каталога разработчика.
Разные типы страниц в одном документе
CSS-свойство page назначает элементу именованный шаблон страницы. Так титульный лист, оглавление, обычная глава, альбомная таблица и приложение могут иметь разные размеры полей, колонтитулы и ориентацию. Правила @page cover, @page chapter и @page landscape описывают геометрию отдельно, а смена имени страницы создаёт необходимую границу. Это надёжнее, чем пытаться перестраивать все поля классами на body.
@page chapter {
size: A4;
margin: 18mm 16mm 20mm 22mm;
@top-right { content: string(chapter-title); }
@bottom-center { content: counter(page); }
}
@page landscape {
size: A4 landscape;
margin: 14mm;
}
.cover { page: cover; }
.chapter { page: chapter; }
.wide-table { page: landscape; }
Псевдоклассы :first, :left и :right позволяют менять первую, левую и правую страницу конкретного набора. На первой странице главы обычно убирают верхний колонтитул, на внешнем поле разворота меняют положение номера. Различие левой и правой стороны имеет смысл только при выбранной схеме разворотов; для PDF, читаемого по одной странице, сложная зеркальная геометрия может ухудшить восприятие.
Начало главы на правой странице задаётся разрывом до правой стороны. Если предыдущий раздел заканчивается справа, движок вставляет пустую левую страницу. Селектор :blank позволяет убрать с неё номера и колонтитулы, сохранив корректную последовательность. Нельзя удалять такую страницу после генерации сторонней утилитой: тогда изменятся стороны всех следующих разворотов и ссылки на номера страниц могут перестать соответствовать содержанию.
Альбомную страницу следует выделять на уровне крупного контейнера, а не отдельной строки таблицы. Внутри именованной страницы таблица продолжает участвовать в обычной пагинации. Если она длиннее одного листа, повторяющийся thead и правила разрыва строк работают и в альбомной ориентации. Возврат к основному шаблону происходит на следующем блоке с другим значением page.
Нумерацию можно начать заново или продолжить через счётчики, но печатный номер и физический индекс страницы — не одно и то же. Обложка может не показывать цифру, вводная часть — использовать римские числа, а основная — арабские. Закладки и ссылки должны вести к фактической цели независимо от отображаемой подписи. Перед выпуском проверяйте содержание на документе, где каждый раздел занимает разное число страниц, иначе ошибка проявится только на реальных данных.
Итоговый выбор рабочего режима
Графическое окно подходит для изучения параметров и быстрой проверки одного шаблона. Командная строка — для пакетных сценариев, сборочных систем и простого вызова из приложения. Обёртки удобны, когда проекту нужен типизированный API на Java, .NET или PHP. JSON-задания и управляющий протокол выбирают при большом числе параметров и постоянной очереди, но только после измерения нагрузки.
Качество результата определяется сочетанием семантической разметки, аккуратного CSS, доступных ресурсов и строгой обработки ошибок. Prince берёт на себя трудную часть пагинации: колонтитулы, сноски, оглавление, перекрёстные ссылки, книжные развороты, профили PDF и тегирование. Он не заменяет редактора шаблонов и не исправляет неверные данные, зато позволяет один раз формализовать правила и многократно получать одинаково устроенные документы.
Перед первым массовым выпуском создайте эталонный набор, ограничьте доступ движка, закрепите окружение и включите проверку результата. После этого шаблон можно развивать как программный компонент: изменения становятся воспроизводимыми, ошибки — диагностируемыми, а каждый PDF связан с понятными входными данными и версией правил.