跳轉到

Services 與 Helpers

nextpdf/codeigniter 透過 CodeIgniter 4 的 Services 模式提供 DocumentFactory,並以全域 helper 函式 pdf()pdf_document() 封裝常見的 PDF 生成模式,讓開發者無需手動管理服務實例。

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.

Services 工廠

Services::pdf()

namespace Config;

use NextPDF\CodeIgniter\Services as NextPdfServices;

// 在 app/Config/Services.php 中已自動注冊
// 用法:
use Config\Services;

/** @var \NextPDF\Core\Contracts\DocumentFactoryInterface $factory */
$factory = Services::pdf();

// 等同於:
$factory = service('pdf');

Services 方法簽名:

/**
 * 取得 NextPDF DocumentFactory 服務。
 *
 * @param bool $getShared true = 共享單例(預設),false = 每次新建
 */
public static function pdf(bool $getShared = true): DocumentFactoryInterface;

Services::pdfProcess()

// 取得長時間執行的 Process 實例(管理跨文件資源快取)
$process = Services::pdfProcess();
$factory = $process->factory();

適合需要在同一次 CLI 命令中生成大量 PDF 的場景,Process 可複用字型快取與影像快取。

pdf() Helper

pdf() helper 是最簡潔的 PDF 生成方式,適合簡單的一次性 PDF 生成:

// 需先載入 helper
helper('nextpdf');

// 建立文件、生成、直接輸出 bytes
$pdfBytes = pdf(function (\NextPDF\Core\Document $doc): void {
    $doc->addPage();
    $doc->text('Hello, CodeIgniter!', x: 20, y: 30);
});

// 以 HTTP 回應送出
return $response
    ->setHeader('Content-Type', 'application/pdf')
    ->setHeader('Content-Disposition', 'attachment; filename="hello.pdf"')
    ->setBody($pdfBytes);

pdf() 函式簽名

/**
 * 建立並生成 PDF,回傳 bytes。
 *
 * @param callable(\NextPDF\Core\Document): void $builder
 * @param array<string, mixed> $configOverrides
 * @return non-empty-string PDF bytes
 */
function pdf(callable $builder, array $configOverrides = []): string;

pdf_document() Helper

pdf_document() 回傳 Document 物件供鏈式操作,適合複雜的多步驟文件建構:

helper('nextpdf');

$document = pdf_document(
    pageSize: 'A4',
    orientation: 'landscape',
    title: 'Sales Report 2026',
    author: 'Sales Team',
);

// 鏈式操作
$document
    ->addPage()
    ->text('Q1 Sales Report', x: 20, y: 30, fontSize: 24)
    ->newLine()
    ->text('Total Revenue: $1,234,567', x: 20, fontSize: 14);

// 儲存至本機
$document->save('/writable/uploads/report.pdf');

// 或輸出 bytes
$pdfBytes = $document->output();

pdf_document() 函式簽名

/**
 * 建立並回傳 Document 物件。
 *
 * @param non-empty-string $pageSize
 * @param 'portrait'|'landscape' $orientation
 * @param non-empty-string|null $title
 * @param non-empty-string|null $author
 */
function pdf_document(
    string $pageSize = 'A4',
    string $orientation = 'portrait',
    ?string $title = null,
    ?string $author = null,
): \NextPDF\Core\Document;

在控制器中使用

<?php

declare(strict_types=1);

namespace App\Controllers;

use CodeIgniter\HTTP\ResponseInterface;

final class ReportController extends BaseController
{
    /**
     * 下載年度報告 PDF
     */
    public function annual(int $year): ResponseInterface
    {
        helper('nextpdf');

        $pdfBytes = pdf(function (\NextPDF\Core\Document $doc) use ($year): void {
            $doc->addPage();
            $doc->text("Annual Report {$year}", x: 20, y: 30, fontSize: 24);
            $doc->text('Generated by NextPDF', x: 20, y: 250, fontSize: 8);
        }, configOverrides: ['pageSize' => 'A4', 'marginMm' => 20.0]);

        return $this->response
            ->setHeader('Content-Type', 'application/pdf')
            ->setHeader('Content-Disposition', "attachment; filename=\"annual-{$year}.pdf\"")
            ->setHeader('X-Content-Type-Options', 'nosniff')
            ->setHeader('Cache-Control', 'no-store')
            ->setBody($pdfBytes);
    }

    /**
     * 在瀏覽器中內嵌預覽
     */
    public function preview(int $year): ResponseInterface
    {
        helper('nextpdf');

        $document = pdf_document(title: "Annual Report {$year}");
        $document->addPage()->text("Preview: Annual Report {$year}", x: 20, y: 30);

        return $this->response
            ->setHeader('Content-Type', 'application/pdf')
            ->setHeader('Content-Disposition', 'inline')
            ->setBody($document->output());
    }
}

測試

<?php

declare(strict_types=1);

use CodeIgniter\Test\CIUnitTestCase;
use NextPDF\CodeIgniter\Testing\PdfServiceFake;

final class ReportControllerTest extends CIUnitTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        PdfServiceFake::install(); // 將 Services::pdf() 替換為 Fake
    }

    public function testAnnualReportDownload(): void
    {
        $result = $this->withSession()->get('/reports/2026');

        $result->assertStatus(200);
        $result->assertHeader('Content-Type', 'application/pdf');
        PdfServiceFake::assertDocumentCreated();
    }
}

參見