Crear un documento de varias páginas con saltos de página automáticos
De un vistazo
Sección titulada «De un vistazo»Permite crear un documento cuyo contenido se extienda por muchas páginas y agregar contenido de forma incremental. Con setAutoPageBreak() activado, el motor de maquetación inicia automáticamente una página nueva cuando el cursor llega al margen inferior. Después de save(), se lee el número final de páginas con getNumPages(). Esta receta sigue examples/05-multi-page.php.
Durante save(), el motor escribe las marcas de cada página en un flujo de contenido. ISO 32000-2 §7.7.3.3 define el Contents de una página como un único flujo o como un arreglo de flujos concatenados en orden. Por tanto, la salida de varias páginas es una secuencia de objetos de página, no un único búfer.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3No se requiere ninguna extensión opcional. Esta receta funciona con la matriz de backport de PHP 8.1-8.4. Tanto getNumPages() como setAutoPageBreak() son estables desde la versión 1.0.0.
Visión conceptual
Sección titulada «Visión conceptual»Un documento de NextPDF es un árbol de páginas. A medida que se agrega contenido, avanza un cursor interno (getY()). Cuando los saltos de página automáticos están activados, el motor comprueba el espacio vertical restante antes de cada bloque de contenido. Si el bloque no cabe en el espacio disponible sobre el margen inferior, el motor vacía la página actual y llama automáticamente a addPage(). El margen inferior que se pasa a setAutoPageBreak() es el umbral que dispara el salto.
Los atributos de página, como el cuadro de medios, son heredables. ISO 32000-2 §7.7.3.4 especifica que un atributo omitido en un objeto de página se resuelve a partir de un nodo ascendiente del árbol de páginas. NextPDF establece un tamaño de página coherente en todo el documento, de modo que cada página generada comparte la misma geometría y no es necesario repetirlo página por página.
Superficie de la API
Sección titulada «Superficie de la API»La superficie de la API se genera automáticamente a partir de PHPDoc. Esta receta se basa en estos métodos:
Document::createStandalone(): self— construye un documento aislado.setAutoPageBreak(bool $enabled, float $margin = 20): static— activa los saltos de página automáticos.$margines el umbral del margen inferior, en milímetros.addPage(?PageSize $size = null, Orientation $orientation = Orientation::Portrait): static— inicia la primera página, y cualquier página explícita.multiCell(...): static/cell(...): static— emite bloques de texto fluido o fijo. La comprobación del salto de página mide estos bloques.getNumPages(): int— el número de páginas después de la maquetación.
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setAutoPageBreak(true, margin: 25);$doc->addPage();
$doc->setFont('helvetica', '', 11);for ($i = 1; $i <= 60; $i++) { $doc->multiCell(0, 7, "Line {$i}: content flows until the page is full, " . 'then the engine starts a new page automatically.');}
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf');echo 'Pages: ' . $doc->getNumPages() . "\n";Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»Este es el ejemplo completo, listo para el arnés de pruebas. Debe respetar NEXTPDF_COOKBOOK_OUTPUT, que establece el arnés, por lo que no se debe enviar el PDF a STDOUT. No establece entropía propia. Cuando el arnés lo ejecuta, DeterministicMode fija el reloj, el /ID y la marca.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Multi-Page Document');
// Enable automatic page breaks. The 25 mm bottom margin is the trigger:// when the cursor would cross it, the engine flushes the page and adds// a new one before the next block is drawn.$doc->setAutoPageBreak(true, margin: 25);$doc->addPage();
$doc->setFont('helvetica', 'B', 18);$doc->cell(0, 12, 'Multi-Page Document Example', newLine: true);$doc->ln(5);
for ($chapter = 1; $chapter <= 3; $chapter++) { $doc->setFont('helvetica', 'B', 14); $doc->cell(0, 10, "Chapter {$chapter}: Lorem Ipsum", newLine: true); $doc->setFont('helvetica', '', 11);
for ($para = 1; $para <= 5; $para++) { $text = "Paragraph {$para} of Chapter {$chapter}. " . 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' . 'Sed do eiusmod tempor incididunt ut labore et dolore magna ' . 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation ' . 'ullamco laboris nisi ut aliquip ex ea commodo consequat.'; $doc->multiCell(0, 7, $text); $doc->ln(3); } $doc->ln(5);}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT; honour it. STDOUT stays free// for progress text only.$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/multi-page.pdf';$doc->save($out);
echo 'Created multi-page.pdf with ' . $doc->getNumPages() . " pages\n";Casos límite y trampas
Sección titulada «Casos límite y trampas»- Salto de página automático desactivado. Con
setAutoPageBreak(false, …), el contenido que sobrepasa el margen inferior se recorta a la página en vez de fluir, y el documento conserva una sola página. Debe activarse para el contenido fluido. - Un único bloque más alto que la página. El motor divide internamente un
multiCellcuyo texto supera la altura imprimible. Sin embargo, un único bloque indivisible más alto que el área utilizable, por ejemplo una imagen alta, se coloca una sola vez y se desborda. Debe dividirse manualmente. - El primer
addPage()sigue siendo obligatorio.cell()llama aaddPage()bajo demanda cuando no existe ninguna página. Aun así, se debe llamar aaddPage()de forma explícita para que el tamaño y la orientación de la primera página sean deterministas. - Unidades del margen. El margen de
setAutoPageBreak()se expresa en milímetros en el sistema de unidades predeterminado, no en puntos.
Rendimiento
Sección titulada «Rendimiento»getNumPages() es O(1). Lee un contador y no vuelve a maquetar. La memoria escala con el contenido retenido, no con el número de páginas. El motor vacía las páginas terminadas al búfer de salida a medida que se completan: el modelo de streaming de una sola pasada (ADR-001). El presupuesto de 2000 ms / 64 MB cubre documentos de unos cientos de páginas de texto en el host de referencia.
Notas de seguridad
Sección titulada «Notas de seguridad»Esta receta escribe únicamente el texto que proporciona el código. No realiza análisis de entrada, acceso a la red ni deserialización. Todo texto de origen externo debe tratarse como no confiable y acotarse en longitud antes de renderizarlo. El motor no impone automáticamente un límite de tamaño de contenido a nivel de aplicación.
Conformidad
Sección titulada «Conformidad»| Declaración | Especificación | Cláusula | reference_id |
|---|---|---|---|
El Contents de una página es un único flujo o un arreglo ordenado y concatenado de flujos. | ISO 32000-2 | §7.7.3.3 | |
| Un atributo de página heredable que se omite en un objeto de página se resuelve a partir de un nodo ascendiente del árbol de páginas. | ISO 32000-2 | §7.7.3.4 | |
El /ID del tráiler es un identificador de archivo de dos cadenas de bytes (obligatorio en PDF 2.0). | ISO 32000-2 | §7.5.5 |
Perfil de reproducibilidad — estructural (por qué no a nivel de bits). Cada documento guardado lleva un /ID en el tráiler cuyas dos cadenas de bytes son un identificador de archivo (ISO 32000-2 §7.5.5, arriba). El segundo elemento no es estable entre ejecuciones, así que los bytes en bruto difieren entre ejecuciones incluso con contenido idéntico. El arnés compara la estructura normalizada por qpdf, que elimina /ID, /CreationDate y /ModDate. Esta recipe describe cómo NextPDF produce la estructura. No afirma la conformidad con ISO 32000-2 como una declaración general.
Contexto comercial
Sección titulada «Contexto comercial»No aplica. La composición de varias páginas con saltos de página automáticos es una capacidad del nivel Core, sin restricción de Premium.