Lewati ke konten

Tata letak: header, footer, kolom, buklet, dan pengelola halaman

Modul Layout memuat mesin page-furniture di balik fasad Document: header, footer, tata letak multikolom, imposisi buklet jahit pelana, serta operasi halaman struktural. Modul ini kecil dan stabil: enam kelas, semuanya @since 1.0.0.

Terminal window
composer require nextpdf/core:^3

Layout (src/Layout/, enam kelas, @since 1.0.0) adalah lapisan mesin di bawah concern HasLayout. Aplikasi Anda memanggil metode fasad pada Document; trait tersebut merutekan setiap panggilan ke salah satu mesin ini. Manifes menandai modul ini dengan risiko standard dan stabilitas internal, dengan Core sebagai satu-satunya modul yang bergantung padanya. Gunakan melalui fasad, bukan dengan membuat kelasnya secara langsung.

HeaderFooter merender header dan footer berulang. Mesin ini menyimpan status judul, deskripsi, logo, fon, margin, dan warna untuk setiap pita. Mesin ini menghasilkan operator aliran konten Portable Document Format (PDF) saat diminta melalui renderHeader() dan renderFooter(). Footer standar mencetak string "page / total" yang diratakan ke kanan. setHeaderCallback() dan setFooterCallback() menggantikan tata letak standar dengan closure yang disediakan pemanggil. getHeaderContentHeight() melaporkan ruang vertikal yang dipakai header, sehingga badan halaman dapat dimulai di bawahnya. Ketika dokumen berada dalam mode tagged-PDF, HasPages menekan header otomatis di tahap hulu karena konten header berada di luar pohon struktur.

ColumnLayout mengelola aliran multikolom. setEqualColumns(int $count, float $totalWidth, float $gap = 5) membagi lebar yang tersedia menjadi kolom-kolom yang sama besar. setColumnsArray() menerima posisi dan lebar ColumnDefinition secara eksplisit. Gunakan selectColumn() untuk memilih kolom, atau nextColumn() untuk berpindah ke kolom berikutnya. getCurrentColumnX() / getCurrentColumnWidth() mengembalikan geometri kolom aktif. Jumlah kolom yang tidak valid, jarak negatif, atau lebar kolom hasil perhitungan yang tidak positif akan melempar PageLayoutException.

BookletLayout menyusun ulang halaman untuk penjilidan jahit pelana (lipat tengah). reorderPages() melengkapi daftar halaman menjadi kelipatan empat karena satu lembar buklet menampung empat slot halaman, lalu mengimposisi halaman dari luar ke dalam agar lembar yang dilipat dan distaples terbaca berurutan. getMarginAdjustments() mengembalikan margin dalam (punggung) dan luar (tepi) untuk setiap sisi pada posisi tertentu. getSheetCount() melaporkan jumlah lembar dua sisi yang dibutuhkan untuk suatu jumlah halaman. Penyusunan ulang hanya mengubah penempatan konten. Urutan halaman PDF yang mendasarinya tetap linear, konsisten dengan pohon halaman yang mendefinisikan pengurutan halaman dalam dokumen (ISO 32000-2 §7.7).

PageManager menyediakan operasi halaman struktural yang terpisah dari perenderan konten. movePage(), copyPage(), dan deletePage() beroperasi pada array PageData berdasarkan referensi. Region halaman (addPageRegion(), isInRegion(), getRegionOffset()) mendefinisikan zona larang-tulis. Grup halaman (startPageGroup(), getGroupPageNo()) mendukung penomoran halaman per bagian. PageRegion dan ColumnDefinition adalah dua pembawa nilai yang digunakan oleh mesin-mesin ini. Modul Writer menserialisasi halaman yang dihasilkan menjadi pohon halaman yang entri Kids-nya berupa array referensi tidak langsung ke anak langsung dari sebuah simpul pohon halaman (ISO 32000-2 §7.7.3.2).

SimbolJenisStabilitasSejak
HeaderFooter::setHeaderData(string, string, string, float): selfmetodestable1.0.0
HeaderFooter::setHeaderFont(string, float): self / setHeaderMargin(float): selfmetodestable1.0.0
HeaderFooter::setFooterFont(string, float): self / setFooterMargin(float): selfmetodestable1.0.0
HeaderFooter::setHeaderCallback(Closure): self / setFooterCallback(Closure): selfmetodestable1.0.0
HeaderFooter::getHeaderContentHeight(): floatmetodestable1.0.0
HeaderFooter::renderHeader(float, float, float, float, int, int): stringmetodestable1.0.0
HeaderFooter::renderFooter(float, float, float, float, int, int, string): stringmetodestable1.0.0
ColumnLayout::setEqualColumns(int, float, float): selfmetodestable1.0.0
ColumnLayout::setColumnsArray(array): self / resetColumns(): selfmetodestable1.0.0
ColumnLayout::selectColumn(int): self / nextColumn(): boolmetodestable1.0.0
ColumnLayout::getCurrentColumnX(float): float / getCurrentColumnWidth(float): floatmetodestable1.0.0
BookletLayout::setBooklet(bool, float, float): voidmetodestable1.0.0
BookletLayout::reorderPages(array): arraymetodestable1.0.0
BookletLayout::getMarginAdjustments(int): array{left: float, right: float}metodestable1.0.0
BookletLayout::getSheetCount(int): intmetodestable1.0.0
PageManager::movePage(int, int, array): void / copyPage(int, array): void / deletePage(int, array): voidmetodestable1.0.0
PageManager::addPageRegion(float, float, float, float): void / isInRegion(float, float): boolmetodestable1.0.0
PageManager::getRegionOffset(float, float, float, float): floatmetodestable1.0.0
PageManager::startPageGroup(): void / getGroupPageNo(int): intmetodestable1.0.0
PageRegion / ColumnDefinitionpembawa nilaistable1.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');

Sumber: examples/13-header-footer.php. Header dirender pada setiap panggilan addPage(); footer dirender saat halaman di-flush.

Callback footer mengontrol teks nomor halaman, dan mesin kolom mengalirkan isi ke dua kolom. Anda mengakses kedua mesin melalui 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');

Sumber: pola dari examples/13-header-footer.php.

  • setEqualColumns() menolak jumlah kolom di bawah 1, jarak negatif, atau tata letak apa pun yang lebar kolom hasil perhitungannya tidak positif. Metode ini melempar PageLayoutException alih-alih mengembalikan tata letak yang terdegradasi.
  • selectColumn() mengabaikan indeks di luar jangkauan dan mempertahankan kolom saat ini; metode ini tidak pernah melempar untuk indeks yang tidak valid. nextColumn() mengembalikan false ketika sudah berada pada kolom terakhir.
  • BookletLayout::reorderPages() melengkapi menjadi kelipatan empat dengan halaman kosong yang dikloning dari dimensi halaman terakhir. Daftar halaman yang kosong mengembalikan array kosong. Penyusunan ulang hanya memengaruhi penempatan; indeks movePage() tetap mengacu pada urutan logis.
  • PageManager::movePage(), copyPage(), dan deletePage() diam-diam tidak melakukan apa pun untuk indeks di luar jangkauan; metode-metode ini memvalidasi dengan isset() lalu kembali tanpa memodifikasi array. Verifikasi sendiri indeksnya jika halaman yang hilang merupakan kesalahan pemanggil.
  • getHeaderContentHeight() mengembalikan 0.0 ketika header dinonaktifkan atau tidak memiliki judul maupun deskripsi. Badan halaman kemudian dimulai pada margin atas.
  • Dalam mode tagged-PDF, header otomatis ditekan di tahap hulu. Bangun tata letak yang sadar struktur untuk dokumen yang aksesibel.

Perenderan header dan footer menambahkan operator ke buffer halaman aktif dalam O(konten furniture); biayanya berskala mengikuti judul, deskripsi, dan pemisah yang ditulis, bukan ukuran dokumen. Perhitungan kolom adalah O(1) per panggilan. BookletLayout::reorderPages() adalah O(n) terhadap jumlah halaman, dengan satu lintasan untuk pelengkapan; loop imposisi menyentuh setiap slot yang dilengkapi sekali saja. Uji region PageManager adalah O(region) per titik, dan operasi halaman adalah penyambungan array O(n). Mesin-mesin ini tidak menyimpan status per halaman di sepanjang dokumen, sehingga tidak menambah pertumbuhan memori pada dokumen yang panjang. Biaya memori yang dominan adalah aliran konten yang terakumulasi, yang dibahas dalam konsep streaming dan memori. Gate latensi dan anggaran memori pipeline HyperText Markup Language (HTML) didokumentasikan dalam PERFORMANCE-BUDGETS; gate ini berlaku untuk jalur render HTML dan tidak secara langsung membatasi mesin tata letak ini. performance_budget sebesar 1500 ms / 64 MB adalah amplop kanvas untuk mulai cepat, bukan kontrak per panggilan.

Mesin-mesin ini mengonsumsi string dan path logo yang disediakan pemanggil. Path logo mengalir melalui mesin gambar, yang memvalidasi berkas tersebut sebelum menyematkannya. renderHeader() dan renderFooter() meng-escape teks judul, deskripsi, dan nomor halaman melalui escaper string PDF terpusat sebelum masuk ke aliran konten, sehingga teks pemanggil tidak dapat menembus tata bahasa literal-string. Callback header atau footer menjalankan kode pemanggil dengan tingkat kepercayaan yang sama seperti bagian lain dokumen; perlakukan data eksternal apa pun yang dibacanya sesuai konteks tersebut. Operasi halaman PageManager memindahkan referensi ke PageData yang sudah ada; operasi ini tidak mengurai byte yang tidak tepercaya.

KlaimStandarKlausulBukti
Penyusunan ulang halaman untuk keluaran buklet hanya mengubah penempatan; pohon halaman tetap mendefinisikan pengurutan halaman yang linear dalam dokumen.ISO 32000-2§7.7
Entri Kids dari simpul pohon halaman yang diserialisasi adalah array referensi tidak langsung ke anak langsung dari simpul tersebut.ISO 32000-2§7.7.3.2

Tabel ini memparafrasekan setiap klausul dan mempertahankan istilah glosarium; tabel ini tidak mereproduksi teks normatif.

  • Core/HasLayout trait — concern fasad yang mengatur mesin-mesin tata letak.
  • Core/HasPages trait — ukuran halaman dan margin yang digunakan oleh perhitungan kolom.
  • Writer — pemancar objek PDF dan pohon halaman yang menserialisasi halaman yang sudah ditata.
  • Streaming dan memori — mengapa mesin furniture tidak menyimpan status per halaman, dan bagaimana jalur perenderan yang terikat memori bekerja.
  • Batasan HTML / Streaming (ADR-001) — alasan di balik cakupan streaming sekali lintas.