Введение: Почему HTML+CSS в PDF — это головная боль (и как её решить)
Представьте: вы разрабатываете сайт на PHP, и клиент просит: «Сделай, чтобы кнопка «Скачать PDF» выгружала красивые счета, отчёты или сертификаты». Вы думаете: «Да легко! Возьму HTML-шаблон, накидаю CSS-стилей и сконвертирую в PDF». Но реальность оказывается сложнее: шрифты плывут, таблицы разваливаются, а CSS-свойство flexbox работает через раз.
На Stack Overflow вопрос «How can I add HTML and CSS into PDF» собрал тысячи просмотров. Это значит, что проблема знакома почти каждому PHP-разработчику. В этой статье мы разберём три популярные библиотеки — Dompdf, TCPDF и mPDF — и покажем, как правильно конвертировать HTML с CSS в PDF на PHP.
Вы узнаете:
- Какую библиотеку выбрать для разных задач
- Как подключить CSS-стили (внешние, встроенные, @import)
- Как решить типичные проблемы: кириллица, таблицы, изображения
- Как написать рабочий код для генерации PDF из HTML
Почему нельзя просто взять и сохранить HTML как PDF?
Браузеры отлично рендерят HTML+CSS, но PDF-генераторы — это не браузеры. Они используют собственные движки рендеринга, которые поддерживают не все CSS-свойства. Например:
flexboxиgrid— работают не вездеborder-radius— поддерживается частично@media print— может игнорироваться- Шрифты (особенно кириллица) — требуют подключения
Хорошая новость: современные PHP-библиотеки постоянно улучшаются, и с правильным подходом можно получить PDF, который выглядит почти как в браузере.
Обзор библиотек для конвертации HTML+CSS в PDF на PHP
Рассмотрим три самых популярных инструмента. У каждого свои сильные стороны.
1. Dompdf
Плюсы: лёгкий, простой в установке через Composer, хорошо поддерживает CSS 2.1 и частично CSS3. Отлично подходит для простых документов — счетов, квитанций.
Минусы: слабая поддержка сложных макетов (flexbox, grid), проблемы с большими объёмами HTML.
2. TCPDF
Плюсы: стабильный, мощный, поддерживает Unicode (кириллица), работает без внешних библиотек. Идеален для сложных PDF-файлов с графиками, QR-кодами, многостраничными таблицами.
Минусы: сложный синтаксис, CSS-стили нужно подключать вручную, код получается громоздким.
3. mPDF
Плюсы: лучшая поддержка CSS (включая @media, float, position), отличная работа с кириллицей, поддержка стилей из внешних файлов. Считается «золотой серединой».
Минусы: тяжелее Dompdf, может быть медленным на больших документах.
Рекомендация: для быстрого старта берите Dompdf. Для серьёзных проектов — mPDF. TCPDF — если нужна максимальная гибкость и вы готовы писать больше кода.
Практический пример: Генерация PDF из HTML с помощью Dompdf
Давайте напишем реальный код. Установим Dompdf через Composer:
composer require dompdf/dompdf
Теперь создадим PHP-скрипт, который конвертирует HTML-шаблон в PDF:
<?php
require_once 'vendor/autoload.php';
use Dompdf\Dompdf;
use Dompdf\Options;
// Настройки
$options = new Options();
$options->set('defaultFont', 'DejaVu Sans'); // Поддержка кириллицы
$options->set('isRemoteEnabled', true); // Разрешаем внешние изображения
$dompdf = new Dompdf($options);
// HTML-шаблон
$html = '
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: DejaVu Sans, sans-serif; }
.invoice {
width: 100%;
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
}
h1 {
color: #2c3e50;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #3498db;
color: white;
}
.total {
margin-top: 20px;
text-align: right;
font-size: 18px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="invoice">
<h1>Счёт № 12345</h1>
<p>Дата: ' . date('d.m.Y') . '</p>
<table>
<tr>
<th>Товар</th>
<th>Кол-во</th>
<th>Цена</th>
<th>Сумма</th>
</tr>
<tr>
<td>Хостинг PythonLib</td>
<td>1</td>
<td>500 ₽</td>
<td>500 ₽</td>
</tr>
<tr>
<td>SSL-сертификат</td>
<td>2</td>
<td>300 ₽</td>
<td>600 ₽</td>
</tr>
</table>
<div class="total">Итого: 1 100 ₽</div>
</div>
</body>
</html>
';
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
// Отправляем PDF в браузер
$dompdf->stream('invoice.pdf', array('Attachment' => 0));
?>
Что здесь важно:
- Шрифт
DejaVu Sans— один из немногих, который корректно отображает кириллицу в Dompdf. - Опция
isRemoteEnabledнужна, если вы используете внешние изображения (например, логотип с URL). - CSS-стили прописаны внутри
<style>— это надёжнее, чем внешние файлы.