跳轉到

多頁報告範例

需求套件nextpdf/core 難度:中級

完整程式碼

<?php

declare(strict_types=1);

use NextPDF\Core\Document;
use NextPDF\Core\Navigation\BookmarkManager;
use NextPDF\Core\Navigation\TocBuilder;
use NextPDF\Core\ValueObjects\PageSize;
use NextPDF\Core\ValueObjects\Margin;
use NextPDF\Core\ValueObjects\Position;
use NextPDF\Core\ValueObjects\Color;

// ─── 文件初始化 ───────────────────────────────────────────────
$document = Document::createStandalone(
    pageSize: PageSize::A4,
    margin:   Margin::create(top: 30.0, right: 20.0, bottom: 25.0, left: 20.0),
);

$text    = $document->text();
$drawing = $document->drawing();
$pages   = $document->pages();
$toc     = $document->navigation()->tocBuilder();

// ─── 頁首/頁尾範本(套用至所有頁面)─────────────────────────
$document->pages()->setHeaderTemplate(
    callback: static function (int $pageNumber, int $totalPages) use ($document): void {
        $text    = $document->text();
        $drawing = $document->drawing();

        // 頁首線
        $drawing->line(
            x1: 20.0, y1: 15.0, x2: 190.0, y2: 15.0,
            color: Color::fromHex('#1E3A8A'), width: 0.5,
        );

        // 左側:文件標題
        $text->write(
            text:     '2024 年度業績報告',
            position: Position::at(x: 20.0, y: 10.0),
            fontSize: 8.0,
            fontName: 'NotoSansCJKtc',
            color:    Color::fromHex('#6B7280'),
        );

        // 右側:頁碼
        $text->write(
            text:     "第 {$pageNumber} 頁,共 {$totalPages} 頁",
            position: Position::at(x: 130.0, y: 10.0),
            fontSize: 8.0,
            fontName: 'NotoSansCJKtc',
            color:    Color::fromHex('#6B7280'),
            alignment: 'right',
            maxWidth:  60.0,
        );
    },
    skipFirstPage: true,  // 封面頁不套用頁首
);

$document->pages()->setFooterTemplate(
    callback: static function (int $pageNumber) use ($document): void {
        $text    = $document->text();
        $drawing = $document->drawing();

        $drawing->line(
            x1: 20.0, y1: 280.0, x2: 190.0, y2: 280.0,
            color: Color::fromHex('#E5E7EB'), width: 0.3,
        );

        $text->write(
            text:     '機密文件 — NextPDF 科技有限公司 © 2024',
            position: Position::at(x: 20.0, y: 283.0),
            fontSize: 7.5,
            fontName: 'NotoSansCJKtc',
            color:    Color::fromHex('#9CA3AF'),
            alignment: 'center',
            maxWidth:  170.0,
        );
    },
    skipFirstPage: true,
);

// ─── 第 1 頁:封面 ────────────────────────────────────────────
$coverPage = $pages->add();

$drawing->rectangle(
    x: 0.0, y: 0.0, width: 210.0, height: 297.0,
    fill: Color::fromHex('#1E3A8A'),
);
$drawing->rectangle(
    x: 0.0, y: 200.0, width: 210.0, height: 97.0,
    fill: Color::fromHex('#FFFFFF'),
);

$text->write(
    text:     '2024',
    position: Position::at(x: 105.0, y: 80.0),
    fontSize: 72.0,
    fontName: 'NotoSansCJKtc-Bold',
    color:    Color::fromHex('#FFFFFF'),
    alignment: 'center',
    maxWidth:  160.0,
);
$text->write(
    text:     '年度業績報告',
    position: Position::at(x: 105.0, y: 120.0),
    fontSize: 24.0,
    fontName: 'NotoSansCJKtc-Bold',
    color:    Color::fromHex('#93C5FD'),
    alignment: 'center',
    maxWidth:  160.0,
);
$text->write(
    text:     "NextPDF 科技有限公司\n2025 年 3 月 15 日",
    position: Position::at(x: 105.0, y: 215.0),
    fontSize: 12.0,
    fontName: 'NotoSansCJKtc',
    color:    Color::fromHex('#374151'),
    alignment: 'center',
    maxWidth:  160.0,
    lineHeight: 1.8,
);

// ─── 第 2 頁:目錄(自動生成) ────────────────────────────────
$tocPage = $pages->add();

$text->write(
    text:     '目  錄',
    position: Position::at(x: 20.0, y: 35.0),
    fontSize: 18.0,
    fontName: 'NotoSansCJKtc-Bold',
    color:    Color::fromHex('#111827'),
);

// 目錄在所有頁面渲染後自動填入頁碼
$toc->reservePlaceholder(
    page:     $tocPage,
    position: Position::at(x: 20.0, y: 50.0),
    maxWidth: 170.0,
    style:    'default',
);

// ─── 內容頁面 ────────────────────────────────────────────────
$sections = [
    ['title' => '執行摘要',         'content' => 'executive-summary'],
    ['title' => '市場概況分析',      'content' => 'market-analysis'],
    ['title' => '財務績效',          'content' => 'financial-performance'],
    ['title' => '各部門業績回顧',    'content' => 'department-review'],
    ['title' => '2025 年策略目標',   'content' => 'strategy-2025'],
];

foreach ($sections as $section) {
    $contentPage = $pages->add();

    // 向 TocBuilder 登記章節
    $toc->addEntry(
        title:      $section['title'],
        pageNumber: $contentPage->number(),
        level:      1,
    );

    // 章節標題
    $text->write(
        text:     $section['title'],
        position: Position::at(x: 20.0, y: 35.0),
        fontSize: 16.0,
        fontName: 'NotoSansCJKtc-Bold',
        color:    Color::fromHex('#1E3A8A'),
    );

    $drawing->line(
        x1: 20.0, y1: 46.0, x2: 190.0, y2: 46.0,
        color: Color::fromHex('#1E3A8A'), width: 1.0,
    );

    // 章節內容(PLACEHOLDER — 實際內容依需求填入)
    $text->write(
        text:     "<!-- 本章節內容由應用程式動態填入 -->",
        position: Position::at(x: 20.0, y: 55.0),
        fontSize: 10.0,
        fontName: 'NotoSansCJKtc',
        color:    Color::fromHex('#9CA3AF'),
    );

    // 向書籤管理器登記
    $document->navigation()->bookmarks()->add(
        title: $section['title'],
        page:  $contentPage,
    );
}

// ─── 最後:建立目錄(已知全部頁碼後執行)────────────────────
$toc->build();

// ─── 輸出 ────────────────────────────────────────────────────
$document->save('/output/annual-report-2024.pdf');

程式碼說明

變化延伸

多欄版面

加入圖表(Pro)

延伸閱讀