Pular para o conteúdo
getnextpdf.com

Cabeçalhos, rodapés e documentos de várias páginas

Uma única página raramente é suficiente. Neste tutorial, você escreve um documento que cresce sozinho até três páginas. Você também dá a cada página um cabeçalho que se repete e um rodapé que mostra o número da página.

Você vai escrever um único script, 01-multipage.php. Ele produz um diário de viagem de três páginas em um arquivo PDF (Portable Document Format):

  • As entradas do diário fluem de uma página para outra automaticamente. Você nunca diz onde uma página termina; o motor decide.
  • Um cabeçalho é uma faixa no topo da página que se repete em todas as páginas. O seu mostra o título do documento.
  • Um rodapé é a faixa correspondente na parte inferior. O seu mostra o número da página como 1 / 3, 2 / 3 e 3 / 3.

Tudo funciona apenas com o pacote nextpdf/core: sem arquivos de fontes, sem extensões adicionais e sem rede.

Duas ideias fazem todo o trabalho neste script.

A primeira é a quebra de página automática. À medida que o motor escreve texto, ele acompanha um cursor: o ponto da página onde a próxima linha vai cair. setAutoPageBreak(true, margin: 25) diz ao motor para vigiar esse cursor. Quando ele chega a 25 pontos (cerca de um terço de polegada) da borda inferior, o motor fecha a página e começa uma nova.

A segunda são os elementos fixos da página: o cabeçalho e o rodapé. Você os descreve uma única vez, antes da primeira página. setHeaderData() registra o título e uma breve descrição para a faixa superior. As chamadas de fonte e de margem escolhem a tipografia e a distância da borda da página. Em seguida, o motor desenha esses elementos fixos em cada página que cria, incluindo as páginas que ele adiciona por conta própria.

Crie 01-multipage.php na pasta do seu projeto:

<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Make sure the output folder exists next to this script.
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();
$document->setTitle('NextPDF Travel Journal');
// Configure the header and footer BEFORE the first page.
// The engine repeats them on every page for you.
$document->setHeaderData(title: 'NextPDF Travel Journal', description: 'A multi-page tutorial document');
$document->setHeaderFont('helvetica', 10);
$document->setHeaderMargin(5);
$document->setFooterFont('helvetica', 8);
$document->setFooterMargin(10);
// Turn on automatic page breaks. When the text cursor gets within
// 25 points of the bottom edge, the engine starts a new page.
$document->setAutoPageBreak(true, margin: 25);
$document->addPage();
$document->setFont('helvetica', 'B', 18);
$document->cell(0, 12, 'Travel journal: three days on the coast', newLine: true);
$document->ln(5);
$days = [
1 => 'We followed the shoreline north and counted seventeen lighthouses.',
2 => 'Rain moved in before noon, so we sketched the harbor from a cafe window.',
3 => 'On the last morning the fog lifted and the whole bay turned silver.',
];
foreach ($days as $day => $highlight) {
$document->setFont('helvetica', 'B', 14);
$document->cell(0, 10, "Day {$day}", newLine: true);
$document->setFont('helvetica', '', 11);
for ($entry = 1; $entry <= 12; $entry++) {
$text = "Entry {$entry} of day {$day}. {$highlight} "
. 'The trail hugged the cliffs for most of the afternoon, and every '
. 'turn opened another view of the water. We stopped often to take '
. 'notes, compare maps, and argue happily about where to eat dinner. '
. 'By the time we reached the guesthouse, our boots were soaked and '
. 'our notebooks were full.';
$document->multiCell(0, 7, $text);
$document->ln(3);
}
$document->ln(5);
}
// Ask the engine how many pages the layout produced, then save.
$pages = $document->getNumPages();
$document->save(__DIR__ . '/out/travel-journal.pdf');
echo "Wrote out/travel-journal.pdf with {$pages} pages\n";

Execute-o com php 01-multipage.php. O script imprime uma linha:

Wrote out/travel-journal.pdf with 3 pages

Abra out/travel-journal.pdf e percorra-o. A faixa do título fica no topo das três páginas, e os números das páginas aumentam no canto inferior direito.

O laço de escrita nunca menciona páginas. Ele escreve o título de cada dia com cell(), que coloca uma linha em uma caixa invisível. Ele escreve as entradas com multiCell(), que quebra o texto longo em quantas linhas forem necessárias. Trinta e seis entradas não cabem em uma única página, então a quebra de página automática dispara duas vezes. É assim que o diário fica com exatamente três páginas.

O cabeçalho e o rodapé foram configurados antes da primeira chamada a addPage(). Essa ordem importa: uma página que já foi desenhada não se atualiza depois. Configure os elementos fixos primeiro, e todas as páginas ficam consistentes.

Você nunca desenhou o número da página. O rodapé o imprime por padrão; você apenas escolheu a fonte dele e a distância da borda da página. Enquanto o motor escreve as páginas, ele ainda não pode saber a contagem final. Por isso, deixa um marcador de posição em cada rodapé e preenche o total real quando você salva.

Dois pequenos detalhes arrematam o script. @mkdir cria a pasta out, e o sinal @ mantém o PHP em silêncio quando a pasta já existe. getNumPages() pergunta ao motor quantas páginas o layout produziu, de modo que a mensagem final possa informar a contagem real.

  • Um erro “failed to open stream” na linha require significa que o script não conseguiu encontrar vendor/autoload.php. Execute-o dentro da pasta do projeto que contém vendor/.
  • Tudo fica em uma única página e o final do texto aparece cortado? Então as quebras de página automáticas estão desligadas. Mantenha a linha setAutoPageBreak(true, margin: 25) e mantenha-a acima do laço de escrita.
  • Uma família de fontes digitada incorretamente lança uma exceção que indica o nome da fonte que não pôde encontrar. Verifique a grafia de helvetica e consulte Fontes e marcação para problemas de fontes mais complexos.
  • Para qualquer outra coisa, o centro de resolução de problemas relaciona sintomas com causas, e a referência de erros explica as exceções gerais do motor e como se recuperar de cada uma.

Seus documentos agora podem crescer o quanto for preciso e ainda parecer bem-acabados. No próximo tutorial, você escreve seu conteúdo em HTML (Hypertext Markup Language) e deixa o motor transformá-lo em páginas.

Quando você quiser um controle mais preciso sobre os temas de hoje, duas receitas vão mais a fundo: