Lewati ke konten

Membuat dokumen multihalaman dengan pemenggalan halaman otomatis

Buat dokumen yang mencakup banyak halaman. Tambahkan konten secara bertahap. Saat setAutoPageBreak() aktif, mesin tata letak memulai halaman baru ketika kursor mencapai margin bawah. Setelah save(), baca jumlah halaman akhirnya dengan getNumPages(). Resep ini mengikuti examples/05-multi-page.php.

Selama save(), mesin menulis penanda setiap halaman ke content stream. ISO 32000-2 §7.7.3.3 mendefinisikan Contents pada halaman sebagai satu stream, atau sebagai larik stream yang digabungkan secara berurutan. Karena itu, keluaran multihalaman adalah graf objek halaman, bukan satu buffer tunggal.

Terminal window
composer require nextpdf/core:^3

Tidak ada ekstensi opsional yang diperlukan. Resep ini berjalan pada matriks backport PHP 8.1–8.4. getNumPages() dan setAutoPageBreak() keduanya telah stabil sejak 1.0.0.

Dokumen NextPDF adalah pohon halaman. Saat Anda menambahkan konten, kursor internal (getY()) bergerak turun pada halaman. Ketika pemenggalan halaman otomatis aktif, mesin memeriksa sisa ruang vertikal sebelum setiap blok konten. Jika blok tidak muat di atas margin bawah, mesin mem-flush halaman saat ini dan memanggil addPage() untuk Anda. Margin bawah yang Anda berikan ke setAutoPageBreak() menjadi ambang pemicunya.

Atribut tingkat halaman, seperti media box, dapat diwariskan. ISO 32000-2 §7.7.3.4 menentukan bahwa atribut yang dihilangkan dari objek halaman akan diselesaikan dari simpul leluhur pada pohon halaman. NextPDF menetapkan satu ukuran halaman yang konsisten di seluruh dokumen, sehingga setiap halaman yang dihasilkan menggunakan geometri yang sama, dan Anda tidak perlu mengulanginya untuk tiap halaman.

Permukaan API dihasilkan dari PHPDoc. Resep ini bergantung pada metode berikut:

  • Document::createStandalone(): self — membuat dokumen terisolasi.
  • setAutoPageBreak(bool $enabled, float $margin = 20): static — mengaktifkan pemenggalan halaman otomatis. $margin adalah pemicu margin bawah dalam milimeter.
  • addPage(?PageSize $size = null, Orientation $orientation = Orientation::Portrait): static — memulai halaman pertama serta halaman eksplisit lainnya.
  • multiCell(...): static / cell(...): static — menghasilkan blok teks yang mengalir atau tetap. Pemeriksaan pemenggalan halaman mengukur blok-blok ini.
  • getNumPages(): int — mengembalikan jumlah halaman setelah tata letak.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setAutoPageBreak(true, margin: 25);
$doc->addPage();
$doc->setFont('helvetica', '', 11);
for ($i = 1; $i <= 60; $i++) {
$doc->multiCell(0, 7, "Line {$i}: content flows until the page is full, "
. 'then the engine starts a new page automatically.');
}
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf');
echo 'Pages: ' . $doc->getNumPages() . "\n";

Ini adalah contoh lengkap yang siap dipakai di harness. Contoh ini mengikuti NEXTPDF_COOKBOOK_OUTPUT, yang ditetapkan oleh harness, jadi jangan menampilkan PDF ke STDOUT. Contoh ini tidak menambahkan entropi apa pun sendiri. Ketika harness menjalankannya, DeterministicMode mengunci jam, /ID, dan branding.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Multi-Page Document');
// Enable automatic page breaks. The 25 mm bottom margin is the trigger:
// when the cursor would cross it, the engine flushes the page and adds
// a new one before the next block is drawn.
$doc->setAutoPageBreak(true, margin: 25);
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Multi-Page Document Example', newLine: true);
$doc->ln(5);
for ($chapter = 1; $chapter <= 3; $chapter++) {
$doc->setFont('helvetica', 'B', 14);
$doc->cell(0, 10, "Chapter {$chapter}: Lorem Ipsum", newLine: true);
$doc->setFont('helvetica', '', 11);
for ($para = 1; $para <= 5; $para++) {
$text = "Paragraph {$para} of Chapter {$chapter}. "
. 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '
. 'Sed do eiusmod tempor incididunt ut labore et dolore magna '
. 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '
. 'ullamco laboris nisi ut aliquip ex ea commodo consequat.';
$doc->multiCell(0, 7, $text);
$doc->ln(3);
}
$doc->ln(5);
}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT; honour it. STDOUT stays free
// for progress text only.
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf';
$doc->save($out);
echo 'Created multi-page.pdf with ' . $doc->getNumPages() . " pages\n";
  • Pemenggalan halaman otomatis dinonaktifkan. Dengan setAutoPageBreak(false, …), konten yang melewati margin bawah akan dipotong oleh batas halaman, bukan dialirkan, dan dokumen tetap berada pada satu halaman. Aktifkan fitur ini untuk konten yang mengalir.
  • Satu blok yang lebih tinggi daripada halaman. Mesin secara internal membagi multiCell yang teksnya melebihi tinggi area cetak. Namun, satu blok tak terbagi yang lebih tinggi daripada area yang dapat digunakan, seperti gambar tinggi, ditempatkan sekali dan akan meluap. Pecah blok tersebut sendiri.
  • addPage() pertama tetap diperlukan. cell() memanggil addPage() sesuai kebutuhan ketika tidak ada halaman. Meski begitu, panggil addPage() secara eksplisit agar ukuran dan orientasi halaman pertama tetap deterministik.
  • Satuan margin. Margin setAutoPageBreak() dinyatakan dalam milimeter pada sistem satuan standar, bukan dalam poin.

getNumPages() bersifat O(1). Metode ini hanya membaca penghitung dan tidak menjalankan ulang tata letak. Penggunaan memori berskala sesuai konten yang disimpan, bukan sesuai jumlah halaman. Mesin mem-flush halaman yang sudah selesai ke buffer keluaran begitu halaman tersebut rampung — model streaming sekali jalan (ADR-001). Anggaran 2000 ms / 64 MB mencakup dokumen dengan beberapa ratus halaman teks pada host referensi.

Resep ini hanya menulis teks yang disediakan oleh kode Anda. Resep ini tidak melakukan penguraian masukan, akses jaringan, atau deserialisasi. Perlakukan setiap teks yang bersumber dari luar sebagai tidak tepercaya, dan terapkan batas panjang sebelum teks dirender. Mesin tidak memberlakukan batas ukuran konten tingkat aplikasi untuk Anda.

PernyataanSpesifikasiKlausareference_id
Contents pada halaman adalah satu stream atau larik stream yang digabungkan secara berurutan.ISO 32000-2§7.7.3.3
Atribut halaman yang dapat diwariskan, jika dihilangkan dari objek halaman, akan diselesaikan dari simpul leluhur pada pohon halaman.ISO 32000-2§7.7.3.4
Trailer /ID adalah pengenal berkas yang terdiri dari dua byte-string (wajib pada PDF 2.0).ISO 32000-2§7.5.5

Profil reproduktibilitas — struktural (mengapa bukan bitwise). Setiap dokumen yang disimpan membawa trailer /ID; dua byte-string-nya merupakan pengenal berkas (ISO 32000-2 §7.5.5, di atas). Elemen kedua tidak stabil antar-eksekusi, sehingga byte mentah berbeda antar-eksekusi bahkan untuk konten yang identik. Harness membandingkan struktur yang sudah dinormalisasi oleh qpdf, yang menghapus /ID, /CreationDate, dan /ModDate. Resep ini menjelaskan cara NextPDF menghasilkan struktur tersebut. Resep ini bukan klaim kesesuaian ISO 32000-2 secara menyeluruh.

Tidak berlaku. Komposisi multihalaman dengan pemenggalan halaman otomatis adalah kapabilitas Core, tanpa batasan Premium.