Верхние и нижние колонтитулы и многостраничные документы
Одной страницы редко бывает достаточно. В этом руководстве вы напишете документ, который сам разрастается до трёх страниц. Кроме того, вы добавите на каждую страницу повторяющийся верхний колонтитул и нижний колонтитул с номером страницы.
Что вы создадите
Заголовок раздела «Что вы создадите»Вы напишете один скрипт, 01-multipage.php. Он создаёт трёхстраничный
дневник путешествия в виде файла PDF (Portable Document Format):
- Записи дневника автоматически перетекают со страницы на страницу. Вы никогда не указываете, где заканчивается страница; это решает движок.
- Верхний колонтитул — это полоса в верхней части страницы, которая повторяется на каждой странице. Ваш показывает заголовок документа.
- Нижний колонтитул — это соответствующая полоса внизу. Ваш показывает
номер страницы в виде
1 / 3,2 / 3и3 / 3.
Всё работает с одним лишь пакетом nextpdf/core: без файлов шрифтов, без
дополнительных расширений и без сети.
Шаг 1: создание трёхстраничного дневника
Заголовок раздела «Шаг 1: создание трёхстраничного дневника»Всю работу в этом скрипте выполняют две идеи.
Первая — это автоматический разрыв страницы. По мере того как движок
записывает текст, он отслеживает курсор: точку на странице, куда попадёт
следующая строка. setAutoPageBreak(true, margin: 25) указывает движку
следить за этим курсором. Когда курсор оказывается в 25 пунктах (около
трети дюйма) от нижнего края, движок закрывает страницу и
начинает новую.
Вторая — это оформление страницы: верхний и нижний колонтитулы. Вы
описываете их один раз, перед первой страницей. setHeaderData() задаёт
заголовок и краткое описание для верхней полосы. Вызовы шрифта и полей
выбирают начертание и расстояние от края страницы. Затем движок рисует это
оформление на каждой создаваемой странице, включая страницы, которые он
добавляет сам.
Создайте 01-multipage.php в папке вашего проекта:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Make sure the output folder exists next to this script.@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();$document->setTitle('NextPDF Travel Journal');
// Configure the header and footer BEFORE the first page.// The engine repeats them on every page for you.$document->setHeaderData(title: 'NextPDF Travel Journal', description: 'A multi-page tutorial document');$document->setHeaderFont('helvetica', 10);$document->setHeaderMargin(5);$document->setFooterFont('helvetica', 8);$document->setFooterMargin(10);
// Turn on automatic page breaks. When the text cursor gets within// 25 points of the bottom edge, the engine starts a new page.$document->setAutoPageBreak(true, margin: 25);
$document->addPage();
$document->setFont('helvetica', 'B', 18);$document->cell(0, 12, 'Travel journal: three days on the coast', newLine: true);$document->ln(5);
$days = [ 1 => 'We followed the shoreline north and counted seventeen lighthouses.', 2 => 'Rain moved in before noon, so we sketched the harbor from a cafe window.', 3 => 'On the last morning the fog lifted and the whole bay turned silver.',];
foreach ($days as $day => $highlight) { $document->setFont('helvetica', 'B', 14); $document->cell(0, 10, "Day {$day}", newLine: true);
$document->setFont('helvetica', '', 11); for ($entry = 1; $entry <= 12; $entry++) { $text = "Entry {$entry} of day {$day}. {$highlight} " . 'The trail hugged the cliffs for most of the afternoon, and every ' . 'turn opened another view of the water. We stopped often to take ' . 'notes, compare maps, and argue happily about where to eat dinner. ' . 'By the time we reached the guesthouse, our boots were soaked and ' . 'our notebooks were full.'; $document->multiCell(0, 7, $text); $document->ln(3); } $document->ln(5);}
// Ask the engine how many pages the layout produced, then save.$pages = $document->getNumPages();$document->save(__DIR__ . '/out/travel-journal.pdf');
echo "Wrote out/travel-journal.pdf with {$pages} pages\n";Запустите его командой php 01-multipage.php. Скрипт выводит одну строку:
Wrote out/travel-journal.pdf with 3 pagesОткройте out/travel-journal.pdf и пролистайте его. Полоса с заголовком
располагается вверху всех трёх страниц, а номера страниц отсчитываются в
правом нижнем углу.
Что только что произошло
Заголовок раздела «Что только что произошло»Цикл записи ни разу не упоминает страницы. Он выводит заголовок каждого дня
с помощью cell(), который помещает одну строку в невидимый прямоугольник.
Он выводит записи с помощью multiCell(), который переносит длинный текст на
столько строк, сколько нужно. Тридцать шесть записей не помещаются на одной
странице, поэтому автоматический разрыв страницы срабатывает дважды. Именно
так дневник получается ровно на три страницы.
Верхний и нижний колонтитулы были настроены перед первым вызовом
addPage(). Этот порядок важен: уже нарисованная страница потом не
обновляется. Настройте оформление сначала — и каждая страница получится
согласованной.
Вы нигде не рисовали номер страницы. Нижний колонтитул выводит его по умолчанию; вы лишь выбрали его шрифт и расстояние от края страницы. Пока движок записывает страницы, он ещё не может знать их итоговое число. Поэтому он оставляет в каждом нижнем колонтитуле заполнитель и подставляет настоящее итоговое значение при сохранении.
Два небольших штриха завершают скрипт. @mkdir создаёт папку out, а знак
@ не даёт PHP жаловаться, когда папка уже существует. getNumPages()
запрашивает у движка, сколько страниц дала разметка, чтобы итоговое сообщение
показало реальное число.
Если что-то пошло не так
Заголовок раздела «Если что-то пошло не так»- Ошибка “failed to open stream” в строке
requireозначает, что скрипт не смог найтиvendor/autoload.php. Запускайте его внутри папки проекта, которая содержитvendor/. - Всё умещается на одной странице, а конец текста обрезан? Значит,
автоматические разрывы страниц отключены. Оставьте строку
setAutoPageBreak(true, margin: 25)и держите её выше цикла записи. - Опечатка в семействе шрифта вызывает исключение, которое называет шрифт, не
найденный движком. Проверьте написание
helvetica, а более сложные проблемы со шрифтами разбирает раздел Шрифты и теги. - В остальных случаях центр устранения неполадок связывает симптомы с причинами, а справочник по ошибкам объясняет общие исключения движка и способы восстановления после каждого из них.
Что дальше
Заголовок раздела «Что дальше»Теперь ваши документы могут разрастаться до любой длины и по-прежнему выглядеть законченными. В следующем руководстве вы пишете свой контент на HTML (Hypertext Markup Language) и позволяете движку превратить его в страницы.
Когда вам понадобится более тонкий контроль над сегодняшними темами, два рецепта раскрывают их глубже:
- Создание многостраничного документа подробно описывает разбиение на страницы, включая его краевые случаи.
- Добавление повторяющихся верхних и нижних колонтитулов разбирает каждую настройку верхнего и нижнего колонтитулов, включая их отключение.