Pular para o conteúdo
getnextpdf.com

Imagens, tabelas e listas

Apenas texto raramente resulta em um documento acabado. Neste tutorial você adiciona três blocos de construção do dia a dia: uma imagem, uma tabela e uma lista com marcadores. Você escreve dois pequenos scripts, e cada um produz um arquivo PDF (Portable Document Format) real que você pode abrir imediatamente.

  • 01-image.php — um PDF de uma página com um título e uma imagem quadrada âmbar, posicionada em um ponto exato da página.
  • 02-table-and-lists.php — um PDF de uma página com uma pequena tabela de livros e uma lista com marcadores logo abaixo dela.

Os dois scripts são programas completos. Continue usando a pasta de projeto do primeiro tutorial e salve cada script ao lado do composer.json.

Este script carrega a própria imagem. Uma minúscula imagem PNG (Portable Network Graphics) de 8 x 8 pixels viaja dentro do script como uma string Base64. Base64 é uma forma de escrever dados binários em texto simples, então ela cabe no código-fonte. Em um projeto real você pularia essa parte, porque o seu arquivo de imagem já existe no disco.

Salve isto como 01-image.php e execute com php 01-image.php:

<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// A tiny 8 x 8 pixel amber PNG, stored as text inside this script.
// In a real project the image file already exists on disk, so you
// would skip this block and point image() at your own file.
$pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAEUlEQVR42mP4Oo8bK2IYWhIAq6BngWh/dt4AAAAASUVORK5CYII=';
@mkdir(__DIR__ . '/out');
$pngPath = __DIR__ . '/out/amber-square.png';
$pngBytes = base64_decode($pngBase64, true);
if ($pngBytes === false) {
fwrite(STDERR, "The embedded image data is damaged.\n");
exit(1);
}
file_put_contents($pngPath, $pngBytes);
$document = Document::createStandalone();
$document->setTitle('Tutorial: images');
$document->addPage();
$document->setFont('helvetica', 'B', 20);
$document->cell(0, 26, 'A picture inside a PDF', newLine: true);
$document->setFont('helvetica', '', 12);
$document->cell(0, 18, 'The amber square below comes from a tiny PNG file.', newLine: true);
// Place the image 72 points (one inch) from the left edge and
// 160 points down from the top, printed as a 96 x 96 point square.
$document->image($pngPath, x: 72, y: 160, width: 96, height: 96);
$document->save(__DIR__ . '/out/image.pdf');
echo "Wrote out/image.pdf\n";

Você deve ver Wrote out/image.pdf na tela. Abra out/image.pdf e você encontrará o título, uma linha de texto e um quadrado âmbar.

  • Primeiro o script decodifica a string Base64 de volta em bytes de imagem e os grava em out/amber-square.png. Isso é apenas o truque que torna o tutorial autossuficiente. A lição começa na chamada image(), que lê da mesma forma qualquer arquivo PNG ou JPEG (Joint Photographic Experts Group) existente.
  • @mkdir(__DIR__ . '/out') cria a pasta de saída. O sinal @ oculta o aviso inofensivo que você receberia quando a pasta já existe, de modo que o script pode ser executado duas vezes seguidas.
  • image() recebe um caminho de arquivo mais uma posição e um tamanho de impressão. Posições e tamanhos são medidos em pontos, e 72 pontos equivalem a uma polegada. A origem da página é o canto superior esquerdo, então y: 160 significa 160 pontos para baixo a partir do topo.
  • Pixels e pontos são coisas diferentes. A imagem tem apenas 8 x 8 pixels, mas width: 96, height: 96 a imprime como um quadrado de uma polegada e um terço de largura. Você escolhe o tamanho de impressão; a quantidade de pixels, não.
  • image() coloca a imagem no ponto exato que você indica. Ela não move a posição de escrita que cell() usa. Escrever o texto primeiro e depois posicionar as imagens evita que os dois colidam.
  • O NextPDF lê a imagem apenas de um arquivo local, nunca de um endereço da web. Ele verifica se o arquivo é uma imagem real e compatível antes de incorporá-la. Essa proteção resguarda você quando os nomes de arquivo vêm dos usuários.

Passo 2: Adicionar uma tabela e uma lista com marcadores

Seção intitulada “Passo 2: Adicionar uma tabela e uma lista com marcadores”

Tabelas e listas são conteúdo estruturado. A forma mais rápida de descrever estrutura é o HTML (Hypertext Markup Language), a mesma marcação que as páginas web usam. O NextPDF renderiza um subconjunto compatível de HTML diretamente na página PDF. Nenhum navegador está envolvido.

Salve isto como 02-table-and-lists.php e execute com php 02-table-and-lists.php:

<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
@mkdir(__DIR__ . '/out');
$document = Document::createStandalone();
$document->setTitle('Tutorial: tables and lists');
$document->addPage();
$document->setFont('helvetica', 'B', 20);
$document->cell(0, 26, 'A reading list, two ways', newLine: true);
$document->ln(8);
$html = <<<'HTML'
<h2>The books as a table</h2>
<table border="1" cellpadding="6" style="width: 100%;">
<thead>
<tr style="background-color: #1E3A8A; color: #FFFFFF;">
<th style="width: 50%;">Title</th>
<th style="width: 20%; text-align: center;">Year</th>
<th style="width: 30%; text-align: right;">Pages</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Paper Office</td>
<td style="text-align: center;">2019</td>
<td style="text-align: right;">312</td>
</tr>
<tr style="background-color: #F8FAFC;">
<td>Ink and Pixels</td>
<td style="text-align: center;">2023</td>
<td style="text-align: right;">208</td>
</tr>
</tbody>
</table>
<h2>Why these two books</h2>
<ul>
<li>Short chapters that fit into a lunch break</li>
<li>Worked examples on every page</li>
<li>No jargon without an explanation</li>
</ul>
HTML;
$document->writeHtml($html);
$document->save(__DIR__ . '/out/table-and-lists.pdf');
echo "Wrote out/table-and-lists.pdf\n";

Você deve ver Wrote out/table-and-lists.pdf. O PDF contém um título, uma tabela de três colunas com uma linha de cabeçalho escura e uma lista com marcadores.

  • O script mistura os dois estilos de escrita em uma mesma página. cell() imprime o título grande na posição de escrita atual. Em seguida, writeHtml() faz a tabela e a lista fluírem página abaixo, sob ele.
  • ln(8) adiciona um pequeno espaço vertical, de oito pontos de altura, entre o título e o conteúdo HTML. Sem ele, os dois ficariam colados um ao outro.
  • A tabela usa marcação de tabela comum: <thead> para a linha de cabeçalho, <tbody> para as linhas de dados, <th> para as células de cabeçalho e <td> para as células de dados. border="1" desenha as linhas da grade, e cellpadding="6" adiciona espaço interno em cada célula.
  • As larguras das colunas são porcentagens, como width: 50%. Elas repartem a largura total da tabela, de modo que o layout sobrevive a uma mudança de tamanho de página. A receita Estruturar uma tabela HTML trata em profundidade de cabeçalhos, rodapés e dimensionamento de colunas.
  • Os atributos style usam declarações CSS (Cascading Style Sheets), a linguagem de estilização da web. Cores, alinhamento e larguras funcionam como mostrado aqui. Antes de depender de outras propriedades, consulte a matriz de suporte a CSS.
  • A lista com marcadores é apenas <ul> com um <li> por item. O NextPDF desenha os marcadores e a indentação para você.
  • Um erro mencionando ImageProcessingException significa que o arquivo de imagem não pôde ser lido ou decodificado. Verifique o caminho e confirme se o arquivo está em um formato compatível, como PNG ou JPEG.
  • Um erro mencionando PageLayoutException significa que uma posição ou um tamanho foi rejeitado. Largura e altura devem ser maiores que zero, e o caminho deve apontar para um arquivo local, não para um endereço da web.
  • Os dois erros estão descritos na referência de erros do motor.
  • Se a tabela for renderizada de forma estranha, verifique primeiro a marcação. Cada linha <tr> e cada célula <td> precisa da sua tag de fechamento.
  • Para qualquer outra coisa, comece pelo guia de solução de problemas.

Suas páginas agora podem conter imagens, tabelas e listas. No próximo tutorial você deixa um documento crescer além de uma única página e o mantém organizado com cabeçalhos, rodapés e números de página. Para aprofundar nos temas de hoje, a receita Incorporar imagens em um documento trata dos formatos de imagem e das regras de dimensionamento.