Pular para o conteúdo

Crie um documento de várias páginas com quebras de página automáticas

Crie um documento que se estenda por várias páginas. Adicione conteúdo à medida que avança. Quando setAutoPageBreak() está ativado, o motor de layout inicia uma nova página assim que o cursor atinge a margem inferior. Após save(), leia a contagem final de páginas com getNumPages(). Esta receita segue examples/05-multi-page.php.

Durante save(), o motor grava as marcações de cada página em um stream de conteúdo. A ISO 32000-2 §7.7.3.3 define o Contents de uma página como um único stream ou como um array de streams concatenados em ordem. Portanto, a saída de várias páginas é uma sequência de objetos de página, não um único buffer.

Terminal window
composer require nextpdf/core:^3

Nenhuma extensão opcional é necessária. Esta receita é executada na matriz de backport PHP 8.1–8.4. getNumPages() e setAutoPageBreak() estão estáveis desde a 1.0.0.

Um documento NextPDF é uma árvore de páginas. À medida que você adiciona conteúdo, um cursor interno (getY()) desce pela página. Quando as quebras de página automáticas estão ativadas, o motor verifica o espaço vertical restante antes de cada bloco de conteúdo. Se o bloco não couber acima da margem inferior, o motor descarrega a página atual e chama addPage() por você. A margem inferior que você passa para setAutoPageBreak() é o limite que dispara a quebra.

Atributos no nível da página, como a media box, são herdáveis. A ISO 32000-2 §7.7.3.4 especifica que um atributo omitido de um objeto de página é resolvido a partir de um nó ancestral da árvore de páginas. O NextPDF define um tamanho de página consistente em todo o documento, para que cada página gerada use a mesma geometria e você não precise repeti-lo em cada página.

A superfície da API é gerada a partir do PHPDoc. Esta receita depende destes métodos:

  • Document::createStandalone(): self — constrói um documento isolado.
  • setAutoPageBreak(bool $enabled, float $margin = 20): static — ativa as quebras de página automáticas. $margin é o disparo da margem inferior em milímetros.
  • addPage(?PageSize $size = null, Orientation $orientation = Orientation::Portrait): static — inicia a primeira página e qualquer página explícita.
  • multiCell(...): static / cell(...): static — emitem blocos de texto fluido ou fixo. A verificação de quebra de página mede esses blocos.
  • getNumPages(): int — retorna o número de páginas após o layout.
<?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";

Este é o exemplo completo, pronto para o harness. Ele respeita NEXTPDF_COOKBOOK_OUTPUT, definido pelo harness; portanto, não envie o PDF para o STDOUT. Ele não adiciona entropia própria. Quando executado pelo harness, o DeterministicMode fixa o relógio, o /ID e a 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";
  • Quebra de página automática desativada. Com setAutoPageBreak(false, …), o conteúdo que ultrapassa a margem inferior é recortado na página em vez de fluir, e o documento permanece em uma única página. Ative-a para conteúdo fluido.
  • Um único bloco mais alto que a página. O motor divide internamente um multiCell cujo texto excede a altura imprimível. No entanto, um único bloco indivisível mais alto que a área utilizável, como uma imagem alta, é posicionado uma vez e transborda. Quebre-o você mesmo.
  • O primeiro addPage() ainda é necessário. cell() chama addPage() sob demanda quando não existe nenhuma página. Mesmo assim, chame addPage() explicitamente para que o tamanho e a orientação da primeira página permaneçam determinísticos.
  • Unidades de margem. A margem de setAutoPageBreak() é expressa em milímetros no sistema de unidades padrão, não em pontos.

getNumPages() é O(1). Ele lê um contador e não executa o layout novamente. A memória escala com o conteúdo retido, não com a contagem de páginas. O motor descarrega as páginas concluídas para o buffer de saída conforme elas são finalizadas — o modelo de streaming de passagem única (ADR-001). O orçamento de 2000 ms / 64 MB cobre documentos com algumas centenas de páginas de texto no host de referência.

Esta receita grava apenas o texto que o código fornece. Ela não realiza análise de entrada, acesso à rede nem desserialização. Trate qualquer texto de origem externa como não confiável e aplique um limite de comprimento antes da renderização. O motor não impõe por você um limite de tamanho de conteúdo no nível da aplicação.

DeclaraçãoEspecificaçãoCláusulareference_id
O Contents de uma página é um único stream ou um array ordenado e concatenado de streams.ISO 32000-2§7.7.3.3
Um atributo de página herdável omitido de um objeto de página é resolvido a partir de um nó ancestral da árvore de páginas.ISO 32000-2§7.7.3.4
O /ID do trailer é um identificador de arquivo de duas byte-strings (obrigatório no PDF 2.0).ISO 32000-2§7.5.5

Perfil de reprodutibilidade — estrutural (por que não bit a bit). Todo documento salvo carrega um /ID no trailer cujas duas byte-strings são um identificador de arquivo (ISO 32000-2 §7.5.5, acima). O segundo elemento não é estável entre execuções, portanto os bytes brutos diferem entre execuções mesmo para conteúdo idêntico. O harness compara a estrutura normalizada pelo qpdf, que remove /ID, /CreationDate e /ModDate. Esta receita descreve como o NextPDF produz a estrutura. Ela não afirma a conformidade com a ISO 32000-2 como uma alegação genérica.

Não se aplica. A composição de várias páginas com quebras de página automáticas é um recurso do Core, sem restrição Premium.