Pro 版本
Converter — 深度参考
NextPDF\Pro\Converter 将现有 PDF 导出为带定位的 HTML、简化 SVG 或纯文本,并将文档内容分段为带类型的结构区域。本深度参考枚举公共 API 接口面、运算符覆盖矩阵、行为契约以及失败模式。它是一个内容提取导出器,而非像素级精确的渲染器。
可用性与授权
标题为“可用性与授权”的章节此能力随 NextPDF Pro(nextpdf/pro)一同提供,并通过 Pro 级授权凭据激活。没有该授权的部署不会加载此能力的类。比较版本并获取授权。
没有任何运行时能力标记对本模块进行门控。只要安装并授权了 Pro 包,Converter 类即可解析。
公共 API 接口面
标题为“公共 API 接口面”的章节| 符号 | 参数 | 默认行为 | 返回 | 抛出或失败于 | 说明 |
|---|---|---|---|---|---|
PdfToHtmlConverter::convert() | string $pdfData, ?ConversionConfig $config = null | 将每个含文本的页面导出为一个自包含的 HTML5 文档 | ConversionResult(目标 Html5) | 当 $pdfData 为空时抛出 InvalidArgumentException | Null 配置默认为 ConversionTarget::Html5 |
PdfToSvgConverter::convert() | string $pdfData, int $pageIndex = 0, ?ConversionConfig $config = null | 将一个页面导出为独立的 SVG 文档 | ConversionResult(目标 Svg;pageCount 始终为 1) | 当 $pdfData 为空时抛出 InvalidArgumentException | 超出范围的 $pageIndex 会产生仅含背景的 SVG |
PdfToTextConverter::convert() | string $pdfData | 从所有页面提取解码后的文本,以分页标记分隔 | ConversionResult(目标 PlainText) | 当 $pdfData 为空时抛出 InvalidArgumentException | 只有此目标会解码字面字符串转义 |
PdfToTextConverter::extractPage() | string $pdfData, int $pageIndex | 提取某个从零开始索引页面的解码文本 | string | 不抛出;对缺失页面或空输入返回 '' | 与 convert() 不同,无空输入防护 |
DocumentSegmentationEngine::segment() | string $pdfData | 使用空间与字体启发式将页面内容分类为带类型的结构分段 | NextPDF\Pro\Interop\V1\Segment\DocumentSegmentation | 当输入为空或无法解析 PDF 结构时抛出 InvalidArgumentException | 基于规则;不执行任何 AI 推理 |
ConversionConfig::__construct() | ConversionTarget $target, bool $embedFonts = false, bool $embedImages = true, float $scaleFactor = 1.0, string $cssClass = 'pdf-page' | 不可变的转换设置 | ConversionConfig | — | embedFonts 与 embedImages 被接受,但在 3.1.0 中不被消费 |
ConversionResult::size() | — | 所产生输出的字节长度 | int | — | 公开只读字段:output、target、pageCount、processingTimeMs |
ConversionResult::isValid() | — | 报告输出是否非空 | bool | — | HTML 与 SVG 文档外壳永不为空;应改为检查 pageCount |
ConversionTarget | 字符串枚举 Html5、Svg、PlainText | 选择导出目标 | mimeType(): string, fileExtension(): string | — | fileExtension() 映射到 html、svg、txt |
入口方法签名:
public function convert(string $pdfData, ?ConversionConfig $config = null): ConversionResultpublic function convert( string $pdfData, int $pageIndex = 0, ?ConversionConfig $config = null,): ConversionResultpublic function convert(string $pdfData): ConversionResultpublic function extractPage(string $pdfData, int $pageIndex): stringpublic function segment(string $pdfData): DocumentSegmentation行为契约
标题为“行为契约”的章节输入是原始 PDF 字节;输出是一个 ConversionResult 值对象。三个导出转换器共享同一套扫描模型:定位 stream/endstream 边界,分离 BT/ET 文本块,并解析文本显示运算符。它们不解析交叉引用表,也不对压缩流进行解压。DocumentSegmentationEngine 有所不同:它会解析 trailer、catalog 与页面树,并在分类前对 FlateDecode 页面内容进行解压。
运算符覆盖范围:
| PDF 运算符 | HTML | SVG | Text |
|---|---|---|---|
Tj(显示字符串) | 是 | 是 | 是 |
TJ(显示数组) | 是 | 是 | 是 |
'(移动 + 显示) | 否 | 否 | 是 |
Td / Tm(定位) | 是 | 是 | 不适用 |
Tf(字号) | 是 | 是 | 不适用 |
re(矩形) | 否 | 是 | 否 |
m / l(线段) | 否 | 是 | 否 |
RG(RGB 描边) | 否 | 是(应用于矩形/线段描边) | 否 |
| 曲线、阴影、裁剪、图像 | 否 | 否 | 否 |
- 定位。 每个
BT/ET块从其第一个匹配的Td或Tm解析出一个位置;当两者同时出现时Tm优先。Y 轴从 PDF 用户空间翻转到左上角输出空间。当没有Tf时,字号默认为 12 pt。 - 页面几何。 HTML 与 SVG 假定一个 A4 页面框(595 x 842 pt)并乘以
scaleFactor。SVG 根元素在一个白色背景矩形之上带有相匹配的viewBox、width 与 height 属性。 - 描边颜色。
RG运算符按位置解析,因此一个多次改变描边颜色的流会按最近的前置运算符为每个矩形和线段着色。各分量在转换为十六进制之前被钳制到 0..1 范围。矩形填充始终为黑色;rg填充运算符不被求值。 - 字符串解码。 文本目标按 ISO 32000-2:2020 §7.3.4.2 解码字面字符串转义:命名转义、掩码为一个字节的八进制
\ddd码、反斜杠换行续接,以及孤立反斜杠的移除。HTML 与 SVG 目标在进行 HTML 或 XML 转义后发出括号之间的原始字节;它们不解码转义。 - 输出组装。 文本目标以一个空格连接块文本,并以由空行围起的
--- Page Break ---连接各页。HTML 目标在一个带有所配置 CSS 类和data-page属性的每页容器内,为每个文本块发出一个绝对定位的<div>。 - 确定性。 对于相同的输入与配置,所产生的 HTML、SVG 或文本字节是稳定的。
processingTimeMs是一个挂钟测量值,被排除在确定性范围之外。
边界情形与失败模式
标题为“边界情形与失败模式”的章节- 空输入:每个
convert()与segment()入口都会抛出InvalidArgumentException(“PDF data must not be empty”)。不产生部分输出。extractPage()是例外:它返回''而不抛出。 - 没有
BT/ET的流会被 HTML 与文本转换器跳过。仅由此类流构成的 PDF 会产生零pageCount,并带有空的文本输出或一个不含页面的 HTML 外壳。 isValid()只检查输出是否非空。HTML 与 SVG 转换器总会发出一个文档外壳,因此即使没有找到文本isValid()也保持为true;请使用pageCount(HTML、文本)来检测空提取。- 这三个导出转换器不会对 FlateDecode 内容进行解压。仅含压缩内容的 PDF 通过它们导出的内容极少或为零。
segment()确实会对 FlateDecode 页面流进行解压。 segment()通过每流大小、压缩比以及一个累计预算来限制解压。突破上限的流会降级为空的页面内容,而不会耗尽内存;它不抛出。- 当无法解析 trailer、交叉引用偏移、文档 catalog 或页面树时,
segment()会抛出InvalidArgumentException。 - 页面索引因转换器而异。HTML 与文本转换器仅统计含文本的流;SVG 转换器统计包含任何可识别图形或文本运算符的流。因此同一个
$pageIndex可能指向不同的流。 TJ的数值字距调整被丢弃;数组中的字符串被拼接而不带字形间距。- 不应用字形到 Unicode 的映射。以自定义编码字体排版的文本会按原始字节序列导出。
- 旋转文本、非文本变换以及分栏排布通过首次匹配定位来近似,可能无法重现原始版面。
- 本模块不发生任何密码学操作,因此 FIPS 模式没有模块特定的行为。
一致性
标题为“一致性”的章节NextPDF 针对所引用的条款记录其能力。支持声明描述已实现的行为;它们不是一致性测试结果,也不是认证,且 NextPDF 不持有任何认证。
| 声明 | 规范条款 | 状态 |
|---|---|---|
已解析 Tj 文本显示运算符 | ISO 32000-2:2020 §9.4 | 已验证(单元测试套件) |
已解析 TJ 数组文本显示运算符 | ISO 32000-2:2020 §9.4 | 已验证(单元测试套件) |
已解析 ' 移动并显示运算符(仅文本目标) | ISO 32000-2:2020 §9.4 | 已验证(单元测试套件) |
| 已解码字面字符串转义(仅文本目标) | ISO 32000-2:2020 §7.3.4.2 | 已实现;字节按原样返回,字符集解释在下游 |
已识别 re、m、l 路径构造(SVG 目标) | ISO 32000-2:2020 §8.5.2 | 部分:不含曲线、闭合或绘制模式求值的子集 |
| 完整文本状态机与页面渲染 | — | 不支持(超出范围) |
Converter 解析文本显示运算符以还原内容;它并不实现完整的文本状态机,因此字形定位是近似的,而非与规范精确一致。
开发说明
标题为“开发说明”的章节- 解析对 PDF 字节长度呈线性。内存随输入加上所产生的输出字符串而增长。
performance_budget前置元数据是针对典型办公文档的单次调用参考。 - 转换器以有界的
strpos/substr扫描来解析不受信任的 PDF 字节。它们不执行任何嵌入的 JavaScript,也不追随任何外部引用。请将导出的 HTML 视为不受信任的内容,并针对其目标用途进行转义。 - HTML 输出使用
htmlspecialchars(ENT_QUOTES, HTML5)进行转义;SVG 文本进行 XML 转义。所配置的cssClass在发出前会被转义。 - 配置消费:
scaleFactor应用于 HTML 与 SVG 目标;cssClass仅应用于 HTML;embedFonts与embedImages为保留字段且当前未使用;target字段不会覆盖某个转换器自身的输出格式。 - 导出转换器自 1.9.0 起提供;
DocumentSegmentationEngine自 2.1.0 起提供,并为 Pro MCPsegment_document工具与 Interop 分段契约提供支撑。 - 同一命名空间中的
PdfPageExtractor与PdfPageData是分段引擎的内部实现,并非公共 API。
发布边界
标题为“发布边界”的章节本页仅记录外部可观测的行为以及受支持的公共 API 接口面。内部命名空间路径、辅助类、机制表、运维手册文件名以及工单前缀均超出范围。