Ir al contenido

Inicio rápido de NextPDF con Laravel

En este tutorial se construye un PDF descargable desde un controlador. Después, el mismo trabajo se traslada a un job en cola. Cada fragmento de código corresponde a un comportamiento verificado por la suite de pruebas del paquete.

Ventana de terminal
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Tres puntos de entrada cubren casi todos los casos de uso de Laravel. La facade ofrece la puesta en marcha más rápida. PdfResponse convierte un documento en una respuesta HTTP. Un job en cola mueve la generación pesada fuera del hilo de la solicitud para que el usuario no tenga que esperarla. Este tutorial los recorre uno por uno. Las versiones preparadas para producción, que añaden manejo de errores, se encuentran en /integrations/laravel/production-usage/.

La facade resuelve un documento nuevo desde el contenedor en cada llamada. El contenedor es el registro de servicios de Laravel. Este fragmento de código corresponde al comportamiento verificado por 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'));

2. Respuesta de descarga desde un controlador

Sección titulada «2. Respuesta de descarga desde un controlador»

PdfResponse::download() devuelve una Illuminate\Http\Response con Content-Type: application/pdf, una disposición attachment y los encabezados de seguridad de OWASP. tests/Unit/Laravel/Http/PdfResponseTest.php comprueba el código de estado, el tipo de contenido, el prefijo de la disposición y los encabezados.

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');
}
}

Para obtener una vista previa en línea en el navegador, sustituir download() por inline(). Para documentos grandes, usar streamInline() o streamDownload(). Estos métodos envían el PDF en fragmentos deterministas de 64 KB.

GeneratePdfJob construye y guarda un PDF en un worker de la cola. El closure de construcción recibe el documento resuelto por el contenedor y devuelve el documento configurado. tests/Unit/Laravel/Jobs/GeneratePdfJobTest.php confirma que el job crea el archivo en la ruta de salida exacta.

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),
);

La ruta de salida debe terminar en .pdf. El job valida la ruta en el worker antes de escribir el archivo.

Las versiones de producción añaden manejo explícito de errores, callbacks de éxito y de fallo en el job, y una estrategia de excepciones tipada. Están documentadas por completo en /integrations/laravel/production-usage/.

  • La facade devuelve una instancia de documento distinta en cada resolución. No se debe guardar en caché Pdf::getFacadeRoot() entre documentos lógicos.
  • Si se pasa un nombre de archivo vacío a cualquier factory de PdfResponse, se usa de forma predeterminada document.pdf. La suite de pruebas de respuesta verifica este valor predeterminado.
  • Los nombres de archivo que no son ASCII reciben automáticamente un parámetro RFC 5987 filename*=. Los nombres ASCII no.
  • GeneratePdfJob rechaza el path traversal, los stream wrappers, los bytes nulos y cualquier extensión que no sea .pdf. Lanza InvalidArgumentException en el worker.

Un documento de una sola página se genera con holgura dentro del presupuesto de tiempo por página definido en el front matter. Mover la generación a GeneratePdfJob elimina por completo de la solicitud HTTP el tiempo de construcción del PDF. La solicitud retorna en cuanto se despacha el job.

PdfResponse aplica en sus factories un conjunto fijo de encabezados de OWASP. Sus factories también sanean el nombre de archivo de descarga. El job en cola valida su ruta de salida. La cobertura detallada de amenazas está en /integrations/laravel/security-and-operations/.

Ningún estándar normativo rige este tutorial. Cada fragmento de código se verifica contra el código fuente del paquete. También se verifica contra la prueba correspondiente en tests/.

La salida firmada y PDF/A está disponible con nextpdf/premium. Es una capacidad opcional de Enterprise. El paquete Core documentado aquí no necesita ningún cambio de código para adoptarla. Consultar https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/install/ — instalar y publicar la config
  • /integrations/laravel/production-usage/ — controlador y job con inyección de dependencias y manejo de errores
  • /integrations/laravel/configuration/ — claves de configuración usadas aquí
  • /integrations/laravel/overview/ — arquitectura y ciclos de vida de los bindings