多頁報告範例¶
需求套件: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)¶
延伸閱讀¶
- 圖表報告範例 — 加入長條圖與折線圖
- API 參考:Navigation —
TocBuilder、BookmarkManager完整 API - API 參考:Layout —
PageManager完整 API