跳轉到

PDF 解析器

PdfParser 提供低層級的 PDF 結構解析能力,讀取現有 PDF 文件並提取頁面、物件與元資料。解析器嚴格遵循 PDF 2.0(ISO 32000-2:2020)規格,同時向下相容 PDF 1.4–1.7 的 xref 格式。

PHP Compatibility

This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.

解析器的主要使用場景是配合 PageImport 將既有 PDF 頁面以 Form XObject 形式嵌入新文件。

開啟 PDF 文件

<?php

declare(strict_types=1);

use NextPDF\Artisan\PdfParser;
use NextPDF\Artisan\ValueObjects\ParsedPage;

// 從檔案路徑開啟
$parser = PdfParser::fromFile('/path/to/document.pdf');

// 從 bytes 字串開啟(適用於記憶體中的 PDF)
$parser = PdfParser::fromBytes($pdfBytes);

// 從 PHP stream resource 開啟(適用於大型檔案串流讀取)
$parser = PdfParser::fromStream($fileHandle);

提取頁面

$parser = PdfParser::fromFile('/path/to/source.pdf');

// 取得所有頁面(延遲載入)
/** @var list<ParsedPage> $pages */
$pages = $parser->pages();

// 取得單一頁面(zero-based index)
$firstPage = $parser->page(index: 0);

// 取得頁數
$count = $parser->pageCount(); // positive-int

xref 表解析

PDF 的交叉參考表(cross-reference table)是定位文件內所有物件的索引結構。PdfParser 支援以下三種 xref 格式:

格式 PDF 版本 說明
傳統 xref table PDF 1.0+ 固定寬度 ASCII 格式
xref stream PDF 1.5+ 壓縮二進位格式(通常 FlateDecode)
混合 xref PDF 1.5+ 傳統 table + cross-reference stream 並存
// 取得 xref 資訊(除錯用途)
$xref = $parser->xrefTable();
$objectCount = $xref->count();       // 文件物件總數
$isCompressed = $xref->isStream();   // 是否為壓縮格式

FlateDecode 解壓縮

PDF 物件流與內容流通常以 FlateDecode(zlib)壓縮。解析器自動處理解壓縮,無需手動操作:

// 取得頁面的原始內容串流(已自動解壓)
$contentStream = $firstPage->contentStream(); // string

// 取得頁面資源字典
$resources = $firstPage->resources();
$fonts      = $resources->fonts();    // array<string, PdfFont>
$images     = $resources->images();   // array<string, PdfImage>

支援的串流 Filter:

Filter 說明
FlateDecode zlib/deflate 壓縮(最常見)
ASCIIHexDecode ASCII 十六進位編碼
ASCII85Decode ASCII Base-85 編碼
LZWDecode LZW 壓縮(PDF 1.x 舊格式)

注意CCITTFaxDecodeJBIG2Decode 等影像專用 Filter 僅在影像物件中支援,不適用於內容串流。

物件流(Object Streams)

PDF 1.5+ 引入物件流(Object Streams,類型 /ObjStm),將多個 PDF 物件壓縮儲存於單一串流中。PdfParser 完整支援此格式:

// 直接存取任意 PDF 物件(自動處理物件流解壓)
$catalog  = $parser->object(objectNumber: 1, generation: 0);
$pageTree = $parser->object(objectNumber: 2, generation: 0);

// 枚舉文件中的所有物件流
$objStreams = $parser->objectStreams(); // list<ObjectStream>
foreach ($objStreams as $stream) {
    $containedCount = $stream->count(); // 此串流包含的物件數
}

元資料提取

$meta = $parser->metadata();

$title    = $meta->title();      // ?non-empty-string
$author   = $meta->author();     // ?non-empty-string
$version  = $meta->pdfVersion(); // e.g. '2.0', '1.7'
$pageSize = $parser->page(0)->mediaBox(); // PageSize Value Object

加密 PDF 處理

use NextPDF\Artisan\Config\DecryptionConfig;

$parser = PdfParser::fromFile(
    path: '/path/to/encrypted.pdf',
    decryption: DecryptionConfig::withUserPassword('user-pass'),
);

例外處理

例外類別 觸發條件
PdfParseException 無效的 PDF 結構、魔術位元組錯誤
XrefCorruptedException xref table 損壞或遺失
FilterDecodeException FlateDecode 解壓縮失敗
EncryptedPdfException 需要密碼但未提供
UnsupportedFilterException 遇到不支援的 Filter 類型

參見