跳转到内容

NextPDF Laravel 快速入门

在本教程中,你将从一个控制器生成可下载的 PDF。接着,你会把同一项工作移到队列任务中执行。每段代码片段都对应一项已由软件包测试套件验证的行为。

Terminal window
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

三个入口点几乎覆盖所有 Laravel 使用场景。facade(门面)让你能最快上手。PdfResponse 会将文档转换为 HTTP 响应。队列任务会把繁重的生成工作移出请求线程,让用户无需等待。本教程会依序说明这三种方式。加入错误处理的生产环境版本位于 /integrations/laravel/production-usage/。

每次调用 facade 时,都会从容器中 resolve(解析)出一份全新的文档。容器是 Laravel 的服务注册表。这段代码片段对应 tests/Unit/Laravel/Facades/PdfTest.php 所验证的行为。

resource: src/Laravel/Facades/Pdf.php + PdfTest.php
<?php
declare(strict_types=1);
use NextPDF\Laravel\Facades\Pdf;
Pdf::addPage();
Pdf::cell(0, 10, 'Hello from Laravel', newLine: true);
Pdf::save(storage_path('app/hello.pdf'));

PdfResponse::download() 会返回一个 Illuminate\Http\Response,其中包含 Content-Type: application/pdfattachment 处置方式,以及 OWASP 安全标头。tests/Unit/Laravel/Http/PdfResponseTest.php 会检查状态码、内容类型、处置方式前缀和标头。

resource: src/Laravel/Http/PdfResponse.php + PdfResponseTest.php
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Illuminate\Http\Response;
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Http\PdfResponse;
final class ReportController extends Controller
{
public function download(): Response
{
$document = app(PdfDocumentInterface::class);
$document->addPage();
$document->cell(0, 10, 'Monthly report', newLine: true);
return PdfResponse::download($document, 'report.pdf');
}
}

若要在浏览器中内嵌预览,只需把 download() 换成 inline()。对于大型文档,请改用 streamInline()streamDownload()。这两个方法会按确定性的 64 KB 块发送 PDF。

GeneratePdfJob 会在队列 worker 上构建并保存一份 PDF。构建器 closure 会接收由容器解析出的文档,并返回配置完成的文档。tests/Unit/Laravel/Jobs/GeneratePdfJobTest.php 会确认任务在指定的输出路径创建该文件。

resource: src/Laravel/Jobs/GeneratePdfJob.php + GeneratePdfJobTest.php
<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch(
storage_path('app/reports/january-2026.pdf'),
static fn (PdfDocumentInterface $document): PdfDocumentInterface => $document
->addPage()
->cell(0, 10, 'January report', newLine: true),
);

输出路径必须以 .pdf 结尾。任务会在 worker 上写入前先验证该路径。

生产环境版本加入了明确的错误处理、任务上的成功与失败回调,以及类型化的异常处理策略。其完整说明文档位于 /integrations/laravel/production-usage/。

  • facade 每次解析都会返回不同的文档实例。请勿在多份逻辑文档之间缓存 Pdf::getFacadeRoot()
  • 传给任何 PdfResponse 工厂的空文件名都会默认为 document.pdf。响应测试套件会验证这项默认值。
  • 非 ASCII 文件名会自动获得一个 RFC 5987 filename*= 参数。 ASCII 文件名则不会。
  • GeneratePdfJob 会拒绝路径遍历、stream 包装器、null 字节,以及任何非 .pdf 的扩展名。它会在 worker 上抛出 InvalidArgumentException

单页文档的生成时间远低于 front-matter 中设定的每页挂钟预算。把生成工作移到 GeneratePdfJob,可将 PDF 构建时间完全从 HTTP 请求中移除。请求会在任务派发后立即返回。

PdfResponse 工厂会应用一组固定的 OWASP 标头。这些工厂也会清理下载文件名。队列任务会验证其输出路径。详尽的威胁覆盖说明位于 /integrations/laravel/security-and-operations/。

没有任何规范性标准约束这份教程。每段代码片段都已对照软件包源代码验证。本教程也已对照 tests/ 下的对应测试验证。

签名与 PDF/A 输出可通过 nextpdf/premium 获得。这是一项可选的 Enterprise 功能。此处所述的 Core 软件包无需更改任何代码即可使用它。请参阅 https://nextpdf.dev/get-license/?intent=laravel-signing

  • /integrations/laravel/install/ —— 安装并发布 config
  • /integrations/laravel/production-usage/ —— 采用 DI 注入且带错误处理的控制器与任务
  • /integrations/laravel/configuration/ —— 此处用到的 config 键
  • /integrations/laravel/overview/ —— 架构与绑定生命周期