產生可供下游工具擷取的文字內容
NextPDF Core 是 PDF 產生端(producer),不提供任何公開的 PDF 轉文字讀取器。在 Core 的脈絡下,「擷取文字內容」指的是你在製作文件時,就讓其中的文字可被擷取。這些字元攜帶 /ToUnicode CMap,文件也具備已加標籤的邏輯結構。接著,符合規範的閱讀器或下游擷取工具就能依閱讀順序還原 Unicode 文字。
從任意第三方 PDF 把文字讀取出來,是取用端(consumer)要處理的事。這項工作屬於 Inspect 模組的旁掛元件或外部工具,不是 Core 產生端介面的一部分。
composer require nextpdf/core:^3概念總覽
標題為「概念總覽」的區段內容串流中的文字呈現運算子會把文字放置到頁面上(ISO 32000-2 §9.4.3)。字元碼並不是 Unicode。/ToUnicode CMap 讓閱讀器能把這些字碼對映回 Unicode 以供擷取(ISO 32000-2 §9.10.2)。已加標籤的結構樹會記錄邏輯閱讀順序,因此擷取時會依文件順序,而非繪製順序,還原文字(ISO 32000-2 §14.8)。
enableTaggedPdf() 會建立這個結構樹,並為內嵌子集字型保留 /ToUnicode CMap。這個組合讓輸出能被可靠擷取。
API 介面
標題為「API 介面」的區段Document::enableTaggedPdf(string $lang = 'en') 會建立結構樹,並設定符合性模式,以便保留 /ToUnicode CMap。Document::setLanguage(string $lang) 會記錄 BCP-47 自然語言。在寫入內容之前,兩者都必須先呼叫。接著使用一般的 setFont() / cell() / multiCell() 介面寫入文字即可。
程式碼範例 — 快速上手
標題為「程式碼範例 — 快速上手」的區段<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setLanguage('en');$doc->enableTaggedPdf('en'); // structure tree + ToUnicode retention$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->multiCell(0, 7, 'This text is extractable by a downstream reader.');
file_put_contents(__DIR__ . '/extractable.pdf', $doc->getPdfData());程式碼範例 — 正式環境
標題為「程式碼範例 — 正式環境」的區段這是可獨立執行、能在測試載具上執行的完整程式。它對應到 範例 examples/38-extract-text-content.php。它會製作一份已加標籤的文件,其文字攜帶 /ToUnicode CMap 與邏輯閱讀順序,接著下游擷取器便能依序還原 Unicode 文字。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$paragraphs = [ 'NextPDF produces documents whose text content is extractable.', 'A tagged structure tree records the logical reading order.', 'The ToUnicode CMap lets a reader recover Unicode from glyph codes.',];
$doc = Document::createStandalone();$doc->setTitle('Extractable text content');$doc->setAuthor('NextPDF Cookbook');$doc->setLanguage('en'); // BCP 47; validated on enableTaggedPdf()
// Configure tagged mode BEFORE content so the structure tree captures the// text in reading order and the /ToUnicode CMap is retained.$doc->enableTaggedPdf('en');
$doc->addPage();$doc->setFont('helvetica', '', 12);foreach ($paragraphs as $p) { $doc->multiCell(0, 7, $p); // captured in reading order $doc->ln(2);}
$pdf = $doc->getPdfData();// $pdf contains a /StructTreeRoot and per-font /ToUnicode CMaps; an external// extractor (or the Inspect sidecar) recovers the Unicode text in order.
echo "Wrote a tagged PDF with extractable text content\n";echo 'Paragraphs authored: ' . count($paragraphs) . "\n";echo "Text is recoverable via the /ToUnicode CMap + tagged reading order.\n";
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the// semantic profile; emit the document to the side-channel.$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');file_put_contents($out !== false && $out !== '' ? $out : __DIR__ . '/extractable.pdf', $pdf);預期的 STDOUT:
Wrote a tagged PDF with extractable text contentParagraphs authored: 3Text is recoverable via the /ToUnicode CMap + tagged reading order.邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- 是產生端,不是讀取器。 Core 沒有公開的
extractText()。從既有的第三方 PDF 中讀出文字是取用端的任務。請改用搭配 Spectrum 旁掛元件的 Inspect 模組,或外部擷取工具。這份範例是讓你自己的輸出可被擷取。 - 先設定標籤。 在寫入內容之前先呼叫
enableTaggedPdf(),結構樹才會依閱讀順序記錄文字。在加入內容之後才呼叫,並不會為先前的內容加上標籤。 - 無效的語言標記。
enableTaggedPdf()會驗證 BCP-47 標記,若遇到無效值,會擲出InvalidConfigException。請使用已註冊的標記,例如en、zh-Hant-TW或ja。 - 純(未加標籤)輸出。 若未呼叫
enableTaggedPdf(),純輸出可能會為了縮小體積,而對使用預定義 CMap 的字型省略/ToUnicodeCMap。如此一來,那些字型的擷取結果就不可靠。當可擷取性很重要時,請為文件加上標籤。
加標籤會新增結構樹並保留 /ToUnicode CMap,使輸出體積略為增加。這項成本與內容量成正比,且不會改變單一遍(single-pass)的繪製模型。
安全性注意事項
標題為「安全性注意事項」的區段已加標籤的文字內容在設計上就是機器可讀。不要把機密放進文件文字中,還期待它們保持隱藏,因為任何拿到該檔案的人,都能擷取可被擷取的文字。這是一份關於產生端正確性的範例,不是機密性控制措施。若需機密性,請參閱加密範例。
符合性
標題為「符合性」的區段| 陳述 | 規範 | 條款 | 參考 ID |
|---|---|---|---|
| ToUnicode CMap 會將字元碼對映到 Unicode,以供文字擷取。 | ISO 32000-2 | §9.10.2 | |
| 文字呈現運算子會在內容串流中將字串放置到頁面上。 | ISO 32000-2 | §9.4.3 | |
| 已加標籤的結構樹會記錄用於擷取的邏輯閱讀順序。 | ISO 32000-2 | §14.8 |
這份範例會產出可被擷取的文字內容。它並未主張符合 PDF/UA-2;那項判定應由檢查工具完成。請參閱無障礙範例。