生成可供下游工具提取的文本内容
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;是否符合应由检查工具判定。请参阅无障碍范例。