跳轉到

頁面匯入

PageImport 子系統將 PdfParser 解析出的 ParsedPage 包裝為 PDF Form XObject,嵌入 NextPDF Core 的 Document 物件中。Form XObject 是 PDF 規格(ISO 32000-2:2020 §8.10)定義的可重用內容流,可在頁面任意位置以任意縮放比例繪製,且資源字典完整隔離,不會與目標文件的資源發生衝突。

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.

核心概念

PdfParser::fromFile()
    └─▶ ParsedPage
            └─▶ PageImporter::import()
                        └─▶ FormXObject (嵌入 Core Document)
                                └─▶ Document::placeXObject() (任意位置渲染)

基本用法:匯入並繪製

<?php

declare(strict_types=1);

use NextPDF\Core\Document;
use NextPDF\Artisan\PdfParser;
use NextPDF\Artisan\PageImport\PageImporter;
use NextPDF\ValueObjects\Position;

// 解析來源 PDF
$parser  = PdfParser::fromFile('/path/to/source.pdf');
$srcPage = $parser->page(index: 0); // 取得第一頁

// 建立目標文件
$document = Document::createStandalone();
$document->addPage();

// 匯入頁面並取得 Form XObject 參照
$importer  = PageImporter::create(document: $document);
$xObjectId = $importer->import(page: $srcPage);

// 在目標文件的指定位置繪製(支援縮放與旋轉)
$document->placeXObject(
    id: $xObjectId,
    position: Position::create(x: 0, y: 0),
    width: 210.0,   // mm,設為 null 則保持原始尺寸
    height: 297.0,
);

$document->save('/tmp/merged.pdf');

批次匯入多頁

$parser   = PdfParser::fromFile('/path/to/multipage.pdf');
$importer = PageImporter::create(document: $document);

// 匯入所有頁面
/** @var list<non-empty-string> $xObjectIds */
$xObjectIds = $importer->importAll(pages: $parser->pages());

// 逐頁在新頁面中渲染(PDF 合併場景)
foreach ($xObjectIds as $index => $xObjectId) {
    $document->addPage();
    $document->placeXObject(
        id: $xObjectId,
        position: Position::create(x: 0, y: 0),
    );
}

模板疊加場景

Form XObject 的核心優勢是可重複繪製——同一個 XObject 可在多個頁面或同一頁面的不同位置繪製,PDF 規格確保只儲存一份資料:

// 載入信紙模板(公司 Logo、頁首、頁尾)
$templateParser = PdfParser::fromFile('/path/to/letterhead.pdf');
$templatePage   = $templateParser->page(0);
$templateId     = $importer->import(page: $templatePage);

// 在 100 頁的報告中每頁疊加模板(XObject 僅儲存一次)
for ($i = 0; $i < 100; $i++) {
    $document->addPage();

    // 先繪製模板(底層)
    $document->placeXObject(id: $templateId, position: Position::create(x: 0, y: 0));

    // 再繪製內容(上層)
    $document->text("第 " . ($i + 1) . " 頁內容", x: 20, y: 50);
}

縮放與定位

use NextPDF\Artisan\PageImport\PlacementConfig;
use NextPDF\ValueObjects\Position;

$document->placeXObject(
    id: $xObjectId,
    config: PlacementConfig::create(
        position: Position::create(x: 10.0, y: 10.0),
        width: 100.0,          // 縮放至 100mm 寬(保持比例)
        height: null,          // null = 根據寬度自動計算高度
        rotation: 90.0,        // 旋轉角度(度,順時針)
        opacity: 0.8,          // 透明度(0.0–1.0)
        clipToBox: true,       // 裁切至媒體框
    ),
);

資源隔離

Form XObject 擁有獨立的資源字典,其字型、影像、色彩空間等資源與目標文件完全隔離。PageImporter 在匯入時自動:

  1. 重新命名資源名稱以避免衝突(F1ArtF1_0 等)
  2. 合併相同字型的子集(節省檔案大小)
  3. 去重複嵌入的影像(相同 content hash 僅儲存一份)

例外處理

例外類別 觸發條件
PageImportException Form XObject 建立失敗
ResourceConflictException 無法解決的資源命名衝突
UnsupportedColorSpaceException 來源頁面使用不支援的色彩空間

參見