Skip to content

Document nhiều trang

Tạo PDF trải qua nhiều trang với auto break, header/footer tùy chỉnh, và đánh số trang.

Ví dụ đầy đủ

php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use TcpdfNext\Document;
use TcpdfNext\Enums\Alignment;

$pdf = Document::create()
    ->setTitle('Annual Report 2026')
    ->setAutoPageBreak(enabled: true, margin: 25);

// -- Trang 1: Trang tiêu đề --------------------------------------------------
$pdf->addPage()
    ->setY(100)
    ->setFont('helvetica', style: 'B', size: 28)
    ->cell(0, 15, 'Annual Report 2026', align: Alignment::Center, newLine: true)
    ->setFont('helvetica', size: 14)
    ->setTextColor(108, 117, 125)
    ->cell(0, 10, 'Acme Corporation', align: Alignment::Center, newLine: true)
    ->setTextColor(33, 37, 41);

// -- Trang nội dung: Chương với auto page break ---------------------------
$chapters = [
    'Executive Summary'    => 'Revenue grew 18% year-over-year to $5.8 billion, driven by strong demand across all product lines and geographic expansion into Southeast Asia.',
    'Market Analysis'      => 'The global widget market reached $42 billion with a 7.2% CAGR. Our market share increased from 12.1% to 13.8%, placing us second worldwide.',
    'Financial Statements' => 'Operating income rose to $870 million. Free cash flow exceeded $400 million, enabling continued investment in R&D and strategic acquisitions.',
];

foreach ($chapters as $title => $body) {
    $pdf->addPage()
        ->setFont('helvetica', style: 'B', size: 20)
        ->cell(0, 12, $title, newLine: true)
        ->setFont('helvetica', size: 11);

    // Lặp nội dung để kích hoạt auto page break
    for ($i = 0; $i < 10; $i++) {
        $pdf->multiCell(0, 7, $body, align: Alignment::Justified);
    }
}

// -- Header & Footer (hậu render) -------------------------------------
$total = $pdf->getNumPages();

for ($p = 2; $p <= $total; $p++) {         // bỏ qua trang tiêu đề
    $pdf->setPage($p)
        // Header
        ->setFont('helvetica', style: 'I', size: 8)
        ->setTextColor(150, 150, 150)
        ->setXY(15, 8)
        ->cell(0, 5, 'Acme Corporation -- Annual Report 2026')
        // Footer
        ->setXY(0, 285)
        ->cell(210, 5, "Page {$p} of {$total}", align: Alignment::Center);
}

$pdf->setTextColor(33, 37, 41)
    ->save(__DIR__ . '/multi-page.pdf');

echo "PDF created -- {$total} pages." . PHP_EOL;

Khái niệm chính

Auto Page Break

php
->setAutoPageBreak(enabled: true, margin: 25)

Khi con trỏ chạm margin mm từ cạnh dưới, trang mới được chèn tự động và nội dung tiếp tục ở margin trên.

Chèn trang thủ công

php
use TcpdfNext\Enums\Orientation;

->addPage()                                   // A4 portrait (mặc định)
->addPage(orientation: Orientation::Landscape) // bắt buộc landscape

Đánh số trang

TCPDF-Next không chèn số trang tự động. Dùng cách tiếp cận hai lượt -- viết mọi nội dung trước, rồi đóng dấu số trên mỗi trang:

php
$total = $pdf->getNumPages();

for ($p = 1; $p <= $total; $p++) {
    $pdf->setPage($p)
        ->setXY(0, 285)
        ->cell(210, 5, "Page {$p} of {$total}", align: Alignment::Center);
}

TIP

Tổng số trang không biết được cho đến khi mọi nội dung đã được viết, đó là lý do cần pattern hai lượt.

Nhóm trang

Dùng startPageGroup() cho đánh số theo phần (vd: bắt đầu lại từ 1 cho mỗi chương):

php
$pdf->startPageGroup();
$currentGroupPage = $pdf->getGroupPageNo();

Margin

php
use TcpdfNext\Core\Margin;

->setMargins(new Margin(left: 15, top: 20, right: 15))

Hoặc thiết lập riêng lẻ:

php
->setLeftMargin(15)
->setTopMargin(20)
->setRightMargin(15)

Kết quả

Ví dụ này tạo PDF nhiều trang với trang tiêu đề căn giữa, ba chương chảy qua các trang bổ sung qua auto page break, và footer "Page X of Y" trên mỗi trang trừ trang tiêu đề.

Phân phối theo giấy phép LGPL-3.0-or-later.