頁首、頁尾與多頁文件
一頁通常不夠用。在本教學中,您會撰寫一份自行擴展到三頁的文件。您也會為每一頁加上會重複出現的頁首,以及顯示頁碼的頁尾。
您將建立的內容
標題為「您將建立的內容」的區段您將撰寫一支腳本 01-multipage.php。它會產生一份三頁的旅行日誌,並儲存為 PDF(Portable Document Format)檔案:
- 日誌的條目會自動從一頁流動到下一頁。您完全不必指定一頁在哪裡結束;由引擎來決定。
- 頁首是位於頁面頂端、會在每一頁重複出現的橫條。您的頁首會顯示文件標題。
- 頁尾則是位於底部的對應橫條。您的頁尾會以
1 / 3、2 / 3、3 / 3的形式顯示頁碼。
一切只需 nextpdf/core 這一個套件即可執行:不需要字型檔案、不需要額外的擴充功能,也不需要網路。
步驟 1:建立這份三頁的日誌
標題為「步驟 1:建立這份三頁的日誌」的區段這支腳本靠兩個概念完成所有工作。
第一個是自動換頁。當引擎寫入文字時,它會追蹤一個游標:頁面上下一行文字將要落腳的位置。setAutoPageBreak(true, margin: 25) 會告訴引擎去留意那個游標。當它接近底部邊緣、距離不到 25 點(約三分之一英吋)時,引擎便會結束目前這一頁,並開始新的一頁。
第二個則是頁面上的固定元素:頁首與頁尾。您只需在第一頁之前描述它們一次。setHeaderData() 會為頂端的橫條記錄標題與一段簡短的說明。字型與邊距的呼叫則決定字體樣式,以及與頁面邊緣的距離。接著,引擎會在它建立的每一頁上繪製這些固定元素,包括它自行新增的頁面。
在您的專案資料夾中建立 01-multipage.php:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Make sure the output folder exists next to this script.@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();$document->setTitle('NextPDF Travel Journal');
// Configure the header and footer BEFORE the first page.// The engine repeats them on every page for you.$document->setHeaderData(title: 'NextPDF Travel Journal', description: 'A multi-page tutorial document');$document->setHeaderFont('helvetica', 10);$document->setHeaderMargin(5);$document->setFooterFont('helvetica', 8);$document->setFooterMargin(10);
// Turn on automatic page breaks. When the text cursor gets within// 25 points of the bottom edge, the engine starts a new page.$document->setAutoPageBreak(true, margin: 25);
$document->addPage();
$document->setFont('helvetica', 'B', 18);$document->cell(0, 12, 'Travel journal: three days on the coast', newLine: true);$document->ln(5);
$days = [ 1 => 'We followed the shoreline north and counted seventeen lighthouses.', 2 => 'Rain moved in before noon, so we sketched the harbor from a cafe window.', 3 => 'On the last morning the fog lifted and the whole bay turned silver.',];
foreach ($days as $day => $highlight) { $document->setFont('helvetica', 'B', 14); $document->cell(0, 10, "Day {$day}", newLine: true);
$document->setFont('helvetica', '', 11); for ($entry = 1; $entry <= 12; $entry++) { $text = "Entry {$entry} of day {$day}. {$highlight} " . 'The trail hugged the cliffs for most of the afternoon, and every ' . 'turn opened another view of the water. We stopped often to take ' . 'notes, compare maps, and argue happily about where to eat dinner. ' . 'By the time we reached the guesthouse, our boots were soaked and ' . 'our notebooks were full.'; $document->multiCell(0, 7, $text); $document->ln(3); } $document->ln(5);}
// Ask the engine how many pages the layout produced, then save.$pages = $document->getNumPages();$document->save(__DIR__ . '/out/travel-journal.pdf');
echo "Wrote out/travel-journal.pdf with {$pages} pages\n";使用 php 01-multipage.php 執行它。這支腳本會印出一行:
Wrote out/travel-journal.pdf with 3 pages開啟 out/travel-journal.pdf 並上下捲動瀏覽。標題橫條位於全部三頁的頂端,頁碼則在右下角依序遞增。
剛才發生了什麼事
標題為「剛才發生了什麼事」的區段這段寫入迴圈從未提及頁面。它以 cell() 寫出每一天的標題,把一行文字放進一個看不見的方框裡。它以 multiCell() 寫出各個條目,將長文字依需要換行成任意多行。三十六則條目無法容納在一頁上,因此自動換頁觸發了兩次。日誌就是這樣剛好變成三頁的。
頁首與頁尾是在第一次呼叫 addPage() 之前設定的。這個順序很重要:頁面一旦繪製完成,之後就不會再更新。先設定好這些固定元素,每一頁的呈現才會一致。
您從未親自繪製頁碼。頁尾預設就會印出它;您只選擇了它的字型,以及它與頁面邊緣的距離。當引擎正在寫入各頁時,它還無法得知最終的頁數。因此它會在每個頁尾留下一個預留位置,並在您儲存時填入真正的總頁數。
還有兩個小細節讓這支腳本更為完整。@mkdir 會建立 out 資料夾,而 @
符號會在資料夾已存在時讓 PHP 保持安靜。getNumPages() 會詢問引擎這份版面配置產生了多少頁,讓最後的訊息能夠回報真正的頁數。
如果出了問題
標題為「如果出了問題」的區段- 若
require那一行出現「failed to open stream」錯誤,代表腳本找不到vendor/autoload.php。請在包含vendor/的專案資料夾內執行它。 - 所有內容都擠在同一頁上,而且文字的結尾被截掉了?那麼自動換頁是關閉的。請保留
setAutoPageBreak(true, margin: 25)這一行,並讓它位於寫入迴圈之前。 - 拼錯的字型系列會拋出一個例外,並指出它找不到的字型。請檢查
helvetica的拼字,並參閱字型與標記以了解更深入的字型問題。 - 至於其他任何情況,疑難排解中心會將症狀對應到成因,而錯誤參考則會說明引擎的一般例外,以及如何從每一種例外中復原。
下一步
標題為「下一步」的區段您的文件現在可以增長到任意長度,看起來卻依然完整。在 下一個教學中,您會用 HTML(Hypertext Markup Language)撰寫內容,並讓引擎把它轉換成頁面。
當您想對今天的主題有更細緻的掌控時,有兩篇食譜會談得更深入:
- 建立多頁文件詳細說明換頁, 包括它的邊界案例。
- 新增會重複的頁首與頁尾逐一介紹每一項頁首與頁尾的設定,包括如何將它們關閉。