Przejdź do głównej zawartości
getnextpdf.com

Nagłówki, stopki i dokumenty wielostronicowe

Jedna strona rzadko wystarcza. W tym samouczku napiszesz dokument, który samodzielnie rozrasta się do trzech stron. Nadasz też każdej stronie powtarzający się nagłówek oraz stopkę pokazującą numer strony.

Napiszesz jeden skrypt, 01-multipage.php. Tworzy trzystronicowy dziennik podróży w postaci pliku PDF (Portable Document Format):

  • Wpisy w dzienniku przechodzą ze strony na stronę automatycznie. Nigdy nie wskazujesz, gdzie kończy się strona; decyduje o tym silnik.
  • Nagłówek to pasek u góry strony, który powtarza się na każdej stronie. Twój pokazuje tytuł dokumentu.
  • Stopka to odpowiadający mu pasek na dole. Twoja pokazuje numer strony w formacie 1 / 3, 2 / 3 i 3 / 3.

Wszystko działa wyłącznie z pakietem nextpdf/core: bez plików czcionek, bez dodatkowych rozszerzeń i bez sieci.

Za całą pracę w tym skrypcie odpowiadają dwie koncepcje.

Pierwsza to automatyczny podział strony. Gdy silnik zapisuje tekst, śledzi kursor: miejsce na stronie, w którym wyląduje kolejny wiersz. setAutoPageBreak(true, margin: 25) każe silnikowi obserwować ten kursor. Gdy zbliży się na odległość 25 punktów (około jednej trzeciej cala) do dolnej krawędzi, silnik zamyka stronę i rozpoczyna nową.

Druga to stałe elementy strony: nagłówek i stopka. Opisujesz je raz, przed pierwszą stroną. setHeaderData() zapisuje tytuł oraz krótki opis dla górnego paska. Wywołania czcionki i marginesu wybierają krój liter oraz odległość od krawędzi strony. Silnik rysuje potem te elementy na każdej tworzonej stronie, włącznie ze stronami, które dodaje samodzielnie.

Utwórz 01-multipage.php w folderze swojego projektu:

<?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";

Uruchom go poleceniem php 01-multipage.php. Skrypt wypisuje jeden wiersz:

Wrote out/travel-journal.pdf with 3 pages

Otwórz out/travel-journal.pdf i przewiń go. Pasek z tytułem znajduje się u góry wszystkich trzech stron, a numery stron rosną w prawym dolnym rogu.

Pętla zapisująca nigdy nie wspomina o stronach. Nagłówek każdego dnia zapisuje za pomocą cell(), które umieszcza jeden wiersz w niewidzialnym polu. Wpisy zapisuje za pomocą multiCell(), które zawija długi tekst na tylu wierszach, ile potrzeba. Trzydzieści sześć wpisów nie mieści się na jednej stronie, więc automatyczny podział strony uruchamia się dwukrotnie. W ten sposób dziennik liczy dokładnie trzy strony.

Nagłówek i stopka zostały skonfigurowane przed pierwszym wywołaniem addPage(). Ta kolejność ma znaczenie: strona, która została już narysowana, nie zmienia się później. Skonfiguruj najpierw stałe elementy, a każda strona wyjdzie spójnie.

Nigdy nie rysowałeś numeru strony. Stopka wypisuje go domyślnie; wybierasz jedynie jej czcionkę oraz odległość od krawędzi strony. Gdy silnik zapisuje strony, nie może jeszcze znać ostatecznej liczby. Dlatego w każdej stopce pozostawia miejsce zastępcze i uzupełnia rzeczywistą sumę w momencie zapisu.

Dwa drobne szczegóły dopełniają skrypt. @mkdir tworzy folder out, a znak @ wycisza PHP, gdy folder już istnieje. getNumPages() pyta silnik, ile stron powstało w układzie, aby końcowy komunikat mógł podać rzeczywistą liczbę.

  • Błąd „failed to open stream” w wierszu require oznacza, że skrypt nie znalazł vendor/autoload.php. Uruchom go wewnątrz folderu projektu zawierającego vendor/.
  • Wszystko mieści się na jednej stronie, a koniec tekstu jest ucięty? W takim razie automatyczne podziały stron są wyłączone. Zachowaj wiersz setAutoPageBreak(true, margin: 25) i umieść go powyżej pętli zapisującej.
  • Błędnie wpisana rodzina czcionek powoduje wyjątek, który wskazuje nazwę czcionki niemożliwej do odnalezienia. Sprawdź pisownię helvetica i zajrzyj do Czcionki i tagowanie, aby rozwiązać głębsze problemy z czcionkami.
  • W pozostałych przypadkach centrum rozwiązywania problemów łączy objawy z przyczynami, a dokumentacja błędów wyjaśnia ogólne wyjątki silnika oraz sposób radzenia sobie z każdym z nich.

Twoje dokumenty mogą teraz rosnąć do dowolnej długości i wciąż wyglądać na dopracowane. W następnym samouczku zapiszesz treść w HTML (Hypertext Markup Language) i pozwolisz silnikowi zamienić ją w strony.

Gdy zechcesz uzyskać precyzyjniejszą kontrolę nad dzisiejszymi zagadnieniami, dwa przepisy sięgają głębiej: