pdfapi

Счёт из HTML-шаблона

Самый частый сценарий: у вас есть данные заказа, нужен аккуратный PDF для клиента. HTML удобен тем, что верстку можно проверить в браузере, а PDF получится тот же самый.

Сборка шаблона#

Обычный HTML со стилями внутри style. Внешние стили и шрифты тоже работают, но встроенные все же надёжнее, т.к. не нужно ждать загрузки.

html
<style>
  body { font-family: sans-serif; color: #111; }
  table { width: 100%; border-collapse: collapse; }
  td, th { border-bottom: 1px solid #ddd; padding: 8px; text-align: left; }
  tr { break-inside: avoid; }
</style>
<h1>Счёт №42</h1>
<table>
  <tr><th>Услуга</th><th>Кол-во</th><th>Сумма</th></tr>
  <!-- строки подставляются из данных -->
</table>
<h2>Итого: 2 990 ₽</h2>

break-inside: avoid не даёт строке таблицы разорваться между страницами.

Подставьте данные с экранированием#

Всё, что пришло от пользователя (название товара, имя покупателя), экранируйте, иначе символы < и & сломают верстку, а злоумышленник сможет воспользоваться инъекцией.

Python
from html import escape

rows = "".join(
    f"<tr><td>{escape(name)}</td><td>{qty}</td><td>{price * qty} ₽</td></tr>"
    for name, qty, price in items
)

Отправьте с полями страницы#

Поля задаются в запросе, а не в CSS, так они одинаковые на всех страницах документа.

cURL
curl -X POST https://pdfapi.ru/api/v1/convert \
  -H "Authorization: Bearer $PDFAPI_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"source\":\"html\",\"html\":$(jq -Rs . < invoice.html),\"options\":{\"marginTop\":\"20mm\",\"marginBottom\":\"20mm\"}}" \
  -o invoice.pdf

Проверьте результат#

Откройте PDF и пролистайте: таблица не рвётся посреди строки, всё на месте. В заголовке ответа X-Pages-Rendered указано, сколько страниц ушло на документ.

Частые вопросы#

Нужен номер страницы в колонтитуле?

Колонтитулы через API пока не задаются — добавьте номер в саму вёрстку или сделайте каждую страницу отдельным блоком с break-before: page.

Логотип не появился?

Картинки подгружаются только с полным адресом https://… или из data:. Относительный путь img/logo.png не сработает: документу не от чего его отсчитывать.

Фон страницы белый, хотя в CSS задан?

Фон body не печатается, попробуйте задать его блоку-обёртке, см. Параметры страницы.