Изображения, таблицы и списки
Один только текст редко даёт законченный документ. В этом руководстве вы добавите три повседневных строительных блока: изображение, таблицу и маркированный список. Вы напишете два небольших сценария, и каждый из них создаст настоящий файл PDF (Portable Document Format), который можно открыть сразу же.
Что вы создадите
Заголовок раздела «Что вы создадите»01-image.php— одностраничный PDF с заголовком и янтарным квадратным изображением, размещённым в точной позиции на странице.02-table-and-lists.php— одностраничный PDF с небольшой таблицей книг и маркированным списком под ней.
Оба сценария — это законченные программы. Продолжайте использовать папку
проекта из
первого руководства
и сохраняйте каждый сценарий рядом с composer.json.
Шаг 1. Поместите изображение на страницу
Заголовок раздела «Шаг 1. Поместите изображение на страницу»Этот сценарий содержит собственное изображение. Крошечное изображение PNG (Portable Network Graphics) размером 8 x 8 пикселей хранится внутри сценария в виде строки Base64. Base64 — это текстовое представление двоичных данных, поэтому оно может находиться прямо в исходном коде. В реальном проекте вы пропустили бы эту часть, поскольку файл изображения уже существует на диске.
Сохраните это как 01-image.php и запустите командой php 01-image.php:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// A tiny 8 x 8 pixel amber PNG, stored as text inside this script.// In a real project the image file already exists on disk, so you// would skip this block and point image() at your own file.$pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAEUlEQVR42mP4Oo8bK2IYWhIAq6BngWh/dt4AAAAASUVORK5CYII=';
@mkdir(__DIR__ . '/out');
$pngPath = __DIR__ . '/out/amber-square.png';$pngBytes = base64_decode($pngBase64, true);if ($pngBytes === false) { fwrite(STDERR, "The embedded image data is damaged.\n"); exit(1);}file_put_contents($pngPath, $pngBytes);
$document = Document::createStandalone();$document->setTitle('Tutorial: images');$document->addPage();
$document->setFont('helvetica', 'B', 20);$document->cell(0, 26, 'A picture inside a PDF', newLine: true);
$document->setFont('helvetica', '', 12);$document->cell(0, 18, 'The amber square below comes from a tiny PNG file.', newLine: true);
// Place the image 72 points (one inch) from the left edge and// 160 points down from the top, printed as a 96 x 96 point square.$document->image($pngPath, x: 72, y: 160, width: 96, height: 96);
$document->save(__DIR__ . '/out/image.pdf');
echo "Wrote out/image.pdf\n";На экране вы должны увидеть Wrote out/image.pdf. Откройте out/image.pdf,
и вы найдёте заголовок, одну строку текста и янтарный квадрат.
Что только что произошло
Заголовок раздела «Что только что произошло»- Сначала сценарий декодирует строку Base64 обратно в байты изображения и
записывает их в
out/amber-square.png. Это лишь приём для автономного руководства. Урок начинается с вызоваimage(), который точно так же читает любой существующий файл PNG или JPEG (Joint Photographic Experts Group). @mkdir(__DIR__ . '/out')создаёт папку для вывода. Знак@скрывает безобидное предупреждение, которое вы получили бы, если бы папка уже существовала, так что сценарий можно запустить два раза подряд.image()принимает путь к файлу, а также позицию и размер печати. Позиции и размеры измеряются в пунктах, и 72 пункта равны одному дюйму. Начало координат страницы — левый верхний угол, поэтомуy: 160означает 160 пунктов вниз от верхнего края.- Пиксели и пункты — это разные вещи. В изображении всего 8 x 8 пикселей,
но
width: 96, height: 96печатает его как квадрат шириной в одну и одну треть дюйма. Размер печати выбираете вы; количество пикселей его не определяет. image()размещает изображение точно в указанном вами месте. Этот вызов не сдвигает позицию письма, которую используетcell(). Если сначала написать текст, а затем разместить изображения, они не столкнутся друг с другом.- NextPDF читает изображение только из локального файла, никогда из веб-адреса. Перед встраиванием он проверяет, что файл является настоящим, поддерживаемым изображением. Эта защита оберегает вас, когда имена файлов поступают от пользователей.
Шаг 2. Добавьте таблицу и маркированный список
Заголовок раздела «Шаг 2. Добавьте таблицу и маркированный список»Таблицы и списки — это структурированное содержимое. Самый быстрый способ описать структуру — HTML (Hypertext Markup Language), та же разметка, которую используют веб-страницы. NextPDF отрисовывает поддерживаемый набор HTML прямо на странице PDF. Никакой браузер не задействован.
Сохраните это как 02-table-and-lists.php и запустите командой
php 02-table-and-lists.php:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();$document->setTitle('Tutorial: tables and lists');$document->addPage();
$document->setFont('helvetica', 'B', 20);$document->cell(0, 26, 'A reading list, two ways', newLine: true);$document->ln(8);
$html = <<<'HTML'<h2>The books as a table</h2><table border="1" cellpadding="6" style="width: 100%;"> <thead> <tr style="background-color: #1E3A8A; color: #FFFFFF;"> <th style="width: 50%;">Title</th> <th style="width: 20%; text-align: center;">Year</th> <th style="width: 30%; text-align: right;">Pages</th> </tr> </thead> <tbody> <tr> <td>The Paper Office</td> <td style="text-align: center;">2019</td> <td style="text-align: right;">312</td> </tr> <tr style="background-color: #F8FAFC;"> <td>Ink and Pixels</td> <td style="text-align: center;">2023</td> <td style="text-align: right;">208</td> </tr> </tbody></table>
<h2>Why these two books</h2><ul> <li>Short chapters that fit into a lunch break</li> <li>Worked examples on every page</li> <li>No jargon without an explanation</li></ul>HTML;
$document->writeHtml($html);
$document->save(__DIR__ . '/out/table-and-lists.pdf');
echo "Wrote out/table-and-lists.pdf\n";Вы должны увидеть Wrote out/table-and-lists.pdf. PDF содержит заголовок,
таблицу из трёх столбцов с тёмной строкой заголовка и маркированный список.
Что только что произошло
Заголовок раздела «Что только что произошло»- Сценарий сочетает оба стиля письма на одной странице.
cell()печатает крупный заголовок в текущей позиции письма. ЗатемwriteHtml()размещает таблицу и список ниже по странице, под заголовком. ln(8)добавляет небольшой вертикальный отступ высотой в восемь пунктов между заголовком и содержимым HTML. Без него они располагались бы вплотную друг к другу.- Таблица использует обычную табличную разметку:
<thead>для строки заголовка,<tbody>для строк данных,<th>для ячеек заголовка и<td>для ячеек данных.border="1"рисует линии сетки, аcellpadding="6"добавляет свободное пространство внутри каждой ячейки. - Ширины столбцов заданы в процентах, например
width: 50%. Они делят полную ширину таблицы, поэтому вёрстка выдерживает изменение размера страницы. Рецепт Вёрстка HTML-таблицы подробно разбирает заголовки, нижние колонтитулы и задание ширины столбцов. - Атрибуты
styleиспользуют объявления CSS (Cascading Style Sheets) — язык оформления веба. Цвета, выравнивание и ширины работают так, как показано здесь. Прежде чем полагаться на другие свойства, сверьтесь с матрицей поддержки CSS. - Маркированный список — это просто
<ul>с одним<li>на каждый пункт. NextPDF рисует маркеры и отступы за вас.
Если что-то пошло не так
Заголовок раздела «Если что-то пошло не так»- Ошибка с именем
ImageProcessingExceptionозначает, что файл изображения не удалось прочитать или декодировать. Проверьте путь и убедитесь, что файл имеет поддерживаемый формат, например PNG или JPEG. - Ошибка с именем
PageLayoutExceptionозначает, что позиция или размер были отклонены. Ширина и высота должны быть больше нуля, а путь должен указывать на локальный файл, а не на веб-адрес. - Обе ошибки описаны в справочнике по ошибкам движка.
- Если таблица отрисовывается странно, сначала проверьте разметку. Каждой
строке
<tr>и ячейке<td>нужен свой закрывающий тег. - Во всех остальных случаях начните с руководства по устранению неполадок.
Теперь ваши страницы могут содержать изображения, таблицы и списки. В следующем руководстве вы позволите документу вырасти за пределы одной страницы и сохраните его аккуратным с помощью верхних и нижних колонтитулов и номеров страниц. Для более глубокого погружения в сегодняшние темы рецепт Встраивание изображений в документ охватывает форматы изображений и правила задания размера.