Генерация PDF — частая задача в веб-разработке. Отчёты, счета, договоры, прайсы — всё это нужно превращать в красивые файлы. В Yii2 это можно сделать разными способами. Но какой выбрать, чтобы не наступить на грабли? В этой статье разберём три популярных подхода: через Dompdf, mpdf и TCPDF. Покажу примеры, сравню их и дам советы, как не сойти с ума при отладке.
Почему для Yii2 стоит использовать расширения, а не писать велосипед?
Yii2 — это фреймворк, который любит готовые решения. Вместо того чтобы вручную подключать библиотеки и настраивать рендеринг, можно взять готовое расширение из Composer. Почему это удобно? Во-первых, расширения уже интегрированы с Yii2 — они используют его компоненты, настройки и пути. Во-вторых, они решают типовые проблемы: кодировка, шрифты, разрывы страниц. В-третьих, вы получаете поддержку сообщества. Если что-то сломалось — скорее всего, кто-то уже нашёл решение.
Я рекомендую использовать расширения kartik-v/yii2-mpdf или miloschuman/yii2-dompdf. Они проверены временем и имеют хорошую документацию.
Обзор трёх популярных библиотек: Dompdf, mpdf, TCPDF
Чтобы выбрать подходящую библиотеку, нужно понимать их сильные и слабые стороны. Я составил таблицу, которая поможет сориентироваться.
| Библиотека | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Dompdf | Простая установка, поддержка CSS, быстро работает с простыми макетами | Плохо поддерживает float, flexbox, сложные таблицы; медленная на больших объёмах | Для простых документов с минимальной вёрсткой |
| mpdf | Отличная поддержка CSS, вложенных таблиц, Unicode, шрифтов; гибкая настройка | Требователен к памяти, большой размер библиотеки | Для сложных отчётов, счетов, книг с оглавлением |
| TCPDF | Лёгкий, быстрый, не требует дополнительных библиотек; хорош для простых текстовых документов | Слабая поддержка CSS, вёрстка через PHP-методы (неудобно для дизайна) | Для текстовых PDF с минимумом оформления |
Установка и настройка расширения для mpdf в Yii2
Начнём с самого популярного варианта — mpdf. Устанавливаем через Composer:
composer require kartik-v/yii2-mpdfПосле установки нужно настроить компонент в конфигурации приложения. Откройте файл config/web.php и добавьте:
'components' => [
'pdf' => [
'class' => 'kartik\mpdf\Pdf',
'mode' => 'utf-8',
'format' => 'A4',
'orientation' => 'P',
'destination' => 'I',
'cssFile' => '@app/web/css/pdf.css',
'options' => [
'title' => 'Мой документ',
'subject' => 'Отчёт',
],
],
],Разберём параметры:
- mode — кодировка. Всегда ставьте utf-8, чтобы не было проблем с русскими буквами.
- format — размер страницы. Можно использовать A4, Letter, Legal или кастомный массив.
- orientation — ориентация: P (portrait) или L (landscape).
- destination — что делать с PDF: I (inline — показать в браузере), D (download — скачать), F (file — сохранить на сервере), S (string — вернуть строку).
- cssFile — путь к CSS-файлу, который будет применён к HTML перед генерацией.
Теперь можно генерировать PDF в контроллере.
Пример генерации PDF с помощью mpdf
Допустим, у нас есть действие actionInvoice в контроллере. Мы хотим сгенерировать счёт на основе данных из модели Order.
public function actionInvoice($id)
{
$order = Order::findOne($id);
if (!$order) {
throw new NotFoundHttpException('Заказ не найден');
}
$content = $this->renderPartial('invoice', [
'order' => $order,
]);
$pdf = new Pdf([
'mode' => 'utf-8',
'format' => 'A4',
'orientation' => 'P',
'destination' => 'I',
'content' => $content,
'cssFile' => '@app/web/css/pdf.css',
'options' => [
'title' => 'Счёт №' . $order->id,
],
]);
return $pdf->render();
}Обратите внимание: мы используем renderPartial, а не render. Это важно, чтобы в PDF не попал лишний HTML-каркас (хедер, футер, скрипты). В представлении invoice.php пишем обычный HTML с CSS-классами. Например:
<div class="invoice">
<h1>Счёт № <?= $order->id ?></h1>
<p>Дата: <?= $order->created_at ?></p>
<table class="items">
<tr>
<th>Товар</th>
<th>Цена</th>
</tr>
<?php foreach ($order->items as $item): ?>
<tr>
<td><?= $item->name ?></td>
<td><?= $item->price ?></td>
</tr>
<?php endforeach; ?>
</table>
<p class="total">Итого: <?= $order->total ?></p>
</div>После этого в браузере откроется PDF с готовым счётом.
Как добавить водяные знаки и колонтитулы
В mpdf можно легко добавить водяной знак или номер страницы. Для этого используйте методы объекта mPDF после создания экземпляра. Вот пример с водяным знаком:
$pdf = new Pdf([
'mode' => 'utf-8',
// ... другие настройки
]);
$mpdf = $pdf->getApi();
$mpdf->SetWatermarkText('Черновик', 0.2);
$mpdf->showWatermarkText = true;
$mpdf->watermark_font = 'DejaVuSans';
return $pdf->render();Для колонтитулов используйте HTML-разметку в свойствах setHeader и setFooter:
$mpdf->setHeader('<div style="text-align: right;">Страница {PAGENO}</div>');
$mpdf->setFooter('<div style="text-align: center;">ООО "Моя компания"</div>');Переменная {PAGENO} автоматически заменится на номер текущей страницы. Это удобно для отчётов.
Правило: всегда тестируйте PDF на реальных данных
Кажется очевидным, но многие забывают. PDF, сгенерированный на тестовых данных с короткими строками, может выглядеть отлично. А на реальных данных — разъехаться. Особенно это касается таблиц с длинным текстом. Поэтому правило простое: всегда проверяйте генерацию на данных, максимально приближенных к боевым. Используйте длинные названия товаров, большие числа, переносы строк. И только после этого выкатывайте в продакшн.
Что в итоге
Мы разобрали, как генерировать PDF в Yii2 с помощью mpdf. Установили расширение, настроили компонент, создали действие в контроллере и добавили водяные знаки. Вы узнали, чем отличаются Dompdf, mpdf и TCPDF, и в каких случаях их использовать. Теперь вы сможете создавать счета, отчёты и другие документы без лишней головной боли. Главное — помните про лайфхак с очисткой буфера и тестируйте на реальных данных.


