Przejdź do głównej zawartości

Układ: nagłówki, stopki, kolumny, broszura i menedżer stron

Moduł Layout zawiera silniki wyposażenia stron stojące za fasadą Document: nagłówki, stopki, układ wielokolumnowy, impozycję broszury szytej zeszytowo oraz operacje strukturalne na stronach. Moduł jest niewielki i stabilny: sześć klas, wszystkie @since 1.0.0.

Okno terminala
composer require nextpdf/core:^3

Layout (src/Layout/, sześć klas, @since 1.0.0) to warstwa silników stojąca za cechą HasLayout. Aplikacja wywołuje metody fasady na Document; cecha przekazuje każde wywołanie do jednego z tych silników. Manifest oznacza moduł jako ryzyko standard i stabilność internal, a Core jako jedyny moduł zależny. Korzystaj z niego przez fasadę, a nie przez bezpośrednie tworzenie instancji klas.

HeaderFooter renderuje powtarzalny nagłówek i stopkę. Przechowuje stan tytułu, opisu, logo, czcionki, marginesu i koloru dla każdego pasma. Na żądanie emituje operatory strumienia treści formatu Portable Document Format (PDF) przez renderHeader() oraz renderFooter(). Domyślna stopka drukuje ciąg "page / total" wyrównany do prawej. setHeaderCallback() oraz setFooterCallback() zastępują domyślny układ domknięciem dostarczonym przez wywołującego. getHeaderContentHeight() zgłasza pionową przestrzeń zajmowaną przez nagłówek, aby treść strony mogła zaczynać się poniżej niego. Gdy dokument działa w trybie tagged-PDF, HasPages na wcześniejszym etapie łańcucha wyłącza automatyczny nagłówek, ponieważ jego treść znajduje się poza drzewem struktury.

ColumnLayout zarządza przepływem wielokolumnowym. setEqualColumns(int $count, float $totalWidth, float $gap = 5) dzieli dostępną szerokość na równe kolumny. setColumnsArray() przyjmuje jawne pozycje i szerokości ColumnDefinition. Użyj selectColumn(), aby wybrać kolumnę, lub nextColumn(), aby przejść do następnej. getCurrentColumnX() / getCurrentColumnWidth() zwracają geometrię aktywnej kolumny. Nieprawidłowa liczba kolumn, ujemny odstęp lub niedodatnia obliczona szerokość kolumny powoduje zgłoszenie PageLayoutException.

BookletLayout zmienia kolejność stron na potrzeby oprawy szytej zeszytowo (zszywanej w grzbiecie). reorderPages() uzupełnia listę stron do wielokrotności czterech, ponieważ arkusz broszury mieści cztery pozycje stron, a następnie układa strony od zewnątrz do wewnątrz, aby po złożeniu i zszyciu arkusze czytało się po kolei. getMarginAdjustments() zwraca margines wewnętrzny (grzbiet) i zewnętrzny (krawędź) dla każdej strony na danej pozycji. getSheetCount() zgłasza, ile dwustronnych arkuszy wymaga dana liczba stron. Zmiana kolejności wpływa wyłącznie na rozmieszczenie treści. Bazowa sekwencja stron PDF pozostaje liniowa, zgodnie z drzewem stron, które definiuje kolejność stron w dokumencie (ISO 32000-2 §7.7).

PageManager udostępnia operacje strukturalne na stronach, oddzielone od renderowania treści. movePage(), copyPage() i deletePage() operują przez referencję na tablicy PageData. Regiony strony (addPageRegion(), isInRegion(), getRegionOffset()) definiują strefy wyłączone z zapisu. Grupy stron (startPageGroup(), getGroupPageNo()) obsługują numerację stron w obrębie sekcji. PageRegion i ColumnDefinition to dwa nośniki wartości używane przez te silniki. Moduł Writer serializuje powstałe strony do drzewa stron, którego wpis Kids jest tablicą referencji pośrednich do bezpośrednich elementów potomnych węzła drzewa stron (ISO 32000-2 §7.7.3.2).

SymbolRodzajStabilnośćOd wersji
HeaderFooter::setHeaderData(string, string, string, float): selfmetodastabilna1.0.0
HeaderFooter::setHeaderFont(string, float): self / setHeaderMargin(float): selfmetodastabilna1.0.0
HeaderFooter::setFooterFont(string, float): self / setFooterMargin(float): selfmetodastabilna1.0.0
HeaderFooter::setHeaderCallback(Closure): self / setFooterCallback(Closure): selfmetodastabilna1.0.0
HeaderFooter::getHeaderContentHeight(): floatmetodastabilna1.0.0
HeaderFooter::renderHeader(float, float, float, float, int, int): stringmetodastabilna1.0.0
HeaderFooter::renderFooter(float, float, float, float, int, int, string): stringmetodastabilna1.0.0
ColumnLayout::setEqualColumns(int, float, float): selfmetodastabilna1.0.0
ColumnLayout::setColumnsArray(array): self / resetColumns(): selfmetodastabilna1.0.0
ColumnLayout::selectColumn(int): self / nextColumn(): boolmetodastabilna1.0.0
ColumnLayout::getCurrentColumnX(float): float / getCurrentColumnWidth(float): floatmetodastabilna1.0.0
BookletLayout::setBooklet(bool, float, float): voidmetodastabilna1.0.0
BookletLayout::reorderPages(array): arraymetodastabilna1.0.0
BookletLayout::getMarginAdjustments(int): array{left: float, right: float}metodastabilna1.0.0
BookletLayout::getSheetCount(int): intmetodastabilna1.0.0
PageManager::movePage(int, int, array): void / copyPage(int, array): void / deletePage(int, array): voidmetodastabilna1.0.0
PageManager::addPageRegion(float, float, float, float): void / isInRegion(float, float): boolmetodastabilna1.0.0
PageManager::getRegionOffset(float, float, float, float): floatmetodastabilna1.0.0
PageManager::startPageGroup(): void / getGroupPageNo(int): intmetodastabilna1.0.0
PageRegion / ColumnDefinitionnośnik wartościstabilna1.0.0
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Header and Footer');
$doc->setHeaderData(
title: 'NextPDF Example',
description: 'Header and Footer Demonstration',
);
$doc->setHeaderFont('helvetica', 10);
$doc->setHeaderMargin(5);
$doc->setFooterFont('helvetica', 8);
$doc->setFooterMargin(10);
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, 'Document with Header and Footer', newLine: true);
$doc->save(__DIR__ . '/output/13-header-footer.pdf');

Źródło: examples/13-header-footer.php. Nagłówek jest renderowany przy każdym wywołaniu addPage(); stopka jest renderowana, gdy strona jest opróżniana.

Wywołanie zwrotne stopki steruje tekstem numeru strony, a silnik kolumn obsługuje dwukolumnową treść. Dostęp do obu silników odbywa się przez fasadę.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Two-Column Report');
$doc->setFooterCallback(static function (Document $d): void {
$d->setFont('helvetica', '', 8);
$d->text(180.0, 285.0, 'Page ' . ($d->getPage() + 1));
});
$doc->addPage();
$doc->setEqualColumns(2, gap: 8);
$doc->selectColumn(0);
$doc->setFont('helvetica', '', 10);
$doc->multiCell(0, 6, 'Left column flows here.');
$doc->selectColumn(1);
$doc->multiCell(0, 6, 'Right column flows here.');
$doc->save(__DIR__ . '/output/two-column-report.pdf');

Źródło: wzorzec z examples/13-header-footer.php.

  • setEqualColumns() odrzuca liczbę kolumn mniejszą niż 1, ujemny odstęp lub dowolny układ, którego obliczona szerokość kolumny nie jest dodatnia. Zgłasza PageLayoutException zamiast zwracać układ o obniżonej jakości.
  • selectColumn() ignoruje indeks spoza zakresu i zachowuje bieżącą kolumnę; nigdy nie zgłasza wyjątku dla nieprawidłowego indeksu. nextColumn() zwraca false, gdy aktywna jest już ostatnia kolumna.
  • BookletLayout::reorderPages() uzupełnia do wielokrotności czterech pustymi stronami sklonowanymi z wymiarów ostatniej strony. Dla pustej listy stron zwraca pustą tablicę. Zmiana kolejności wpływa wyłącznie na rozmieszczenie; indeksy movePage() nadal odnoszą się do kolejności logicznej.
  • PageManager::movePage(), copyPage() i deletePage() po cichu nic nie robią dla indeksu spoza zakresu; sprawdzają go przez isset() i zwracają sterowanie bez modyfikowania tablicy. Zweryfikuj indeks, gdy brakująca strona jest błędem wywołującego.
  • getHeaderContentHeight() zwraca 0.0, gdy nagłówek jest wyłączony lub nie ma ani tytułu, ani opisu. Treść strony zaczyna się wtedy od górnego marginesu.
  • W trybie tagged-PDF automatyczny nagłówek jest wyłączany na wcześniejszym etapie łańcucha. Dla dokumentów dostępnych zbuduj układ uwzględniający strukturę.

Renderowanie nagłówka i stopki dołącza operatory do bufora aktywnej strony w O(treść wyposażenia); koszt skaluje się z zapisanym tytułem, opisem i separatorem, a nie z rozmiarem dokumentu. Obliczenia kolumn mają złożoność O(1) na wywołanie. BookletLayout::reorderPages() ma złożoność O(n) względem liczby stron, z jednorazowym przebiegiem uzupełniania; pętla impozycji odwiedza każdą uzupełnioną pozycję raz. Testy regionów PageManager mają złożoność O(regiony) na punkt, a operacje na stronach to O(n) dla wycinków tablicy. Te silniki nie zachowują stanu poszczególnych stron w obrębie dokumentu, więc nie zwiększają zużycia pamięci w przypadku długich dokumentów. Dominującym kosztem pamięci jest zgromadzony strumień treści, który opisuje koncepcja strumieniowania i pamięci. Bramka budżetu opóźnień i pamięci potoku HyperText Markup Language (HTML) jest udokumentowana w PERFORMANCE-BUDGETS; jest ograniczona do ścieżki renderowania HTML i nie reguluje bezpośrednio tych silników układu. performance_budget wynoszący 1500 ms / 64 MB to ramowa obwiednia dla szybkiego startu, a nie kontrakt na pojedyncze wywołanie.

Te silniki przyjmują ciągi dostarczone przez wywołującego oraz dostarczoną przez wywołującego ścieżkę do logo. Ścieżka do logo przechodzi przez silnik obrazów, który weryfikuje plik przed jego osadzeniem. renderHeader() i renderFooter() przepuszczają tytuł, opis i tekst numeru strony przez scentralizowany mechanizm ucieczki ciągów PDF, zanim trafią one do strumienia treści, więc tekst wywołującego nie może wyłamać się z gramatyki ciągu literalnego. Wywołanie zwrotne nagłówka lub stopki uruchamia kod wywołującego z tym samym poziomem zaufania co reszta dokumentu; z należytą ostrożnością traktuj wszelkie dane zewnętrzne, które ono odczytuje. Operacje na stronach PageManager przenoszą referencje do istniejących PageData; nie parsują niezaufanych bajtów.

TwierdzenieStandardKlauzulaDowód
Zmiana kolejności stron na potrzeby broszury wpływa wyłącznie na rozmieszczenie; drzewo stron nadal definiuje liniową kolejność stron w dokumencie.ISO 32000-2§7.7
Wpis Kids serializowanego węzła drzewa stron jest tablicą referencji pośrednich do bezpośrednich elementów potomnych tego węzła.ISO 32000-2§7.7.3.2

Tabela parafrazuje każdą klauzulę i pozostawia terminy słownikowe bez zmian; nie odtwarza tekstu normatywnego.