跳轉到

PdfFactory

PdfFactoryNextPDF\Symfony\Service\PdfFactory,封裝底層的 DocumentFactoryInterface,將 Bundle 的 YAML/XML 設定自動轉換為 Configuration 物件,讓控制器和服務無需手動構建 Configuration 即可快速建立文件。


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.

注入 PdfFactory

透過建構子 autowiring 注入(建議方式):

<?php

declare(strict_types=1);

namespace App\Service;

use NextPDF\Core\Document;
use NextPDF\Symfony\Service\PdfFactory;

final class InvoiceGenerator
{
    public function __construct(
        private readonly PdfFactory $pdfFactory,
    ) {}

    public function generate(Invoice $invoice): string
    {
        $document = $this->pdfFactory->create(
            title: "Invoice #{$invoice->id}",
            author: $invoice->company->name,
        );

        $document->addPage();
        $document->text($invoice->summary(), x: 20, y: 30);

        return $document->output();
    }
}

create() 方法簽名

namespace NextPDF\Symfony\Service;

use NextPDF\Core\Document;
use NextPDF\ValueObjects\PageSize;
use NextPDF\ValueObjects\Margin;

final class PdfFactory
{
    /**
     * 建立新文件,使用 Bundle 設定作為預設值,呼叫時的參數可覆寫任何設定。
     *
     * @param non-empty-string|null $title
     * @param non-empty-string|null $author
     */
    public function create(
        ?PageSize $pageSize = null,
        ?Margin $margin = null,
        ?string $title = null,
        ?string $author = null,
        ?string $subject = null,
        bool $taggedPdf = false,
    ): Document;

    /**
     * 從設定陣列建立文件。
     *
     * @param array<string, mixed> $overrides
     */
    public function createFromArray(array $overrides = []): Document;
}

createFromArray() 使用

createFromArray() 適合動態設定場景,例如從資料庫或 API 取得設定:

$document = $this->pdfFactory->createFromArray([
    'page_size'   => 'Letter',
    'orientation' => 'landscape',
    'margin_mm'   => 20.0,
    'title'       => 'Dashboard Export',
    'tagged_pdf'  => true,
]);

設定繼承順序

PdfFactory 在建立 Configuration 物件時,按以下優先順序合併設定:

Bundle 預設值 (nextpdf.document.*)
    ↓ 被覆寫
Bundle YAML 設定
    ↓ 被覆寫
create() / createFromArray() 呼叫時傳入的參數

範例:若 Bundle 設定 margin_mm: 15.0,但呼叫 create(margin: Margin::uniform(25.0)),最終使用 25.0

與 DocumentFactoryInterface 的關係

PdfFactory 是 Symfony-specific 的薄封裝層,底層委派至 DocumentFactoryInterface。如需直接存取 Core 介面:

use NextPDF\Core\Contracts\DocumentFactoryInterface;

// 直接注入 Core 介面(不含 Bundle 設定整合)
public function __construct(
    private readonly DocumentFactoryInterface $coreFactory,
) {}

選擇準則:

使用場景 建議注入
應用程式代碼(控制器、服務) PdfFactory
需要使用 Bundle YAML 設定預設值 PdfFactory
底層函式庫代碼、可重用元件 DocumentFactoryInterface
測試(需要精確控制設定) DocumentFactoryInterface

測試替換

在功能測試中,可替換 PdfFactory 為假物件(fake):

<?php

declare(strict_types=1);

use NextPDF\Symfony\Testing\PdfFactoryFake;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

final class InvoiceGeneratorTest extends KernelTestCase
{
    public function testGeneratesDocument(): void
    {
        PdfFactoryFake::install(static::getContainer());

        $generator = static::getContainer()->get(InvoiceGenerator::class);
        $pdfBytes  = $generator->generate(Invoice::factory()->make());

        PdfFactoryFake::assertCreatedWithTitle('Invoice #1');
        $this->assertNotEmpty($pdfBytes);
    }
}

參見