Pular para o conteúdo

Criar layout de tabela HTML

Use esta receita para renderizar uma tabela Hypertext Markup Language (HTML) com cabeçalho, células alinhadas, bordas e linha de rodapé. Tabelas são um módulo Verified na matriz de suporte de Cascading Style Sheets (CSS). Esta receita segue examples/09-html-table.php.

Terminal window
composer require nextpdf/core:^3

Essa restrição instala o pacote nextpdf/core. O exemplo é executado em PHP 8.4.

O motor HTML usa um pipeline de tabela dedicado (src/Html/Table/). O TableParser coleta linhas e células em um buffer de vida curta; em seguida, o NextPDF faz o layout e desenha a tabela. Esse é o único desvio reconhecido em relação ao modelo sem Document Object Model (DOM) retido descrito na ADR-001. O buffer tem vida curta e fica restrito ao seu contêiner. Ele não é um DOM persistente.

As larguras das colunas seguem o modelo CSS Table. O NextPDF faz o layout da tabela com uma largura usada já determinada e, em seguida, o algoritmo de dimensionamento de colunas define a largura usada de cada coluna (W3C CSS Table Level 3). Com table-layout: fixed, o conteúdo da célula é ignorado no cálculo da largura. Em vez disso, a primeira linha e as larguras explícitas das colunas orientam o layout (W3C CSS Table Level 3).

O CSS Table Level 3 é classificado como Verified na matriz. Quatro fontes fundamentam essa classificação: src/Html/Table/, a suíte de testes unitários de Table, os testes do TableParser e os PDFs golden sintéticos.

Renderize tabelas com writeHtml(string $html): static (NextPDF\Core\Concerns\HasTextOutput). O motor oferece suporte à marcação padrão de tabela. As tags com suporte são table, thead, tbody, tfoot, tr, th e td. Os atributos com suporte são border, cellpadding, cellspacing, colspan e um atributo style por célula. A tabela completa no PHPDoc é gerada a partir do código-fonte.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->writeHtml(
'<table border="1" cellpadding="5"><tr><th>SKU</th><th>Qty</th></tr>'
. '<tr><td>NPD-CORE</td><td style="text-align: right;">1</td></tr></table>'
);
$doc->save(__DIR__ . '/out.pdf');

Este exemplo autocontido pode ser executado pelo harness. Ele reproduz examples/09-html-table.php e mostra um cabeçalho estilizado, linhas com fundo alternado, colunas numéricas alinhadas e um total no rodapé.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('HTML Table');
$doc->addPage();
$html = <<<'HTML'
<h1 style="color: #1E3A8A;">Product Inventory Report</h1>
<table border="1" cellpadding="5" cellspacing="0" style="width: 100%;">
<thead>
<tr style="background-color: #1E3A8A; color: #FFFFFF;">
<th style="width: 10%;">#</th>
<th style="width: 45%;">Product</th>
<th style="width: 20%; text-align: center;">SKU</th>
<th style="width: 25%; text-align: right;">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>NextPDF Core License</td>
<td style="text-align: center;">NPD-CORE</td>
<td style="text-align: right;">$0.00</td>
</tr>
<tr style="background-color: #F8FAFC;">
<td>2</td>
<td>NextPDF Pro License</td>
<td style="text-align: center;">NPD-PRO</td>
<td style="text-align: right;">$299.00</td>
</tr>
</tbody>
<tfoot>
<tr style="background-color: #1E293B; color: #FFFFFF; font-weight: bold;">
<td colspan="3" style="text-align: right;">Grand total:</td>
<td style="text-align: right;">$299.00</td>
</tr>
</tfoot>
</table>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/html-table-layout.pdf');
echo "Wrote html-table-layout.pdf\n";

Saída padrão esperada (STDOUT):

Wrote html-table-layout.pdf
  • Larguras percentuais. As porcentagens de width das colunas são resolvidas em relação à largura usada da tabela. O algoritmo de dimensionamento de colunas normaliza porcentagens que não somam 100. Não presuma larguras exatas em pixels.
  • colspan. Uma célula que abrange várias colunas participa da distribuição de largura entre as colunas que ela cobre. Um total de rodapé que se estende pela maioria das colunas é um padrão comum e tem suporte.
  • Modelo de borda. Em alguns fixtures de tabela, o padrão de border-collapse difere do valor inicial do CSS. Defina essa propriedade diretamente quando a renderização da borda for importante.
  • Rowspan entre quebras de página. Uma célula com rowspan pode cruzar um limite de página; nesse caso, o paginador de rowspan fragmenta essa célula (ADR-007). Uma célula muito alta que não pode ser dividida pode lançar UnsplittableContentException.
  • Células vazias. Um <td> vazio ainda ocupa seu slot na grade. Esse slot não é colapsado.

O buffer da tabela tem vida curta e fica restrito ao seu contêiner. O custo de parsing é linear em relação ao número de células, somado à passagem de dimensionamento de colunas em O(linhas x colunas). O orçamento é wall_ms: 1500, peak_mb: 96. Mantenha uma única tabela dentro do limite da ADR-020, de 5,000 nós por contexto.

Trecho da matriz de suporte de CSS (apenas linhas Verified)

Seção intitulada “Trecho da matriz de suporte de CSS (apenas linhas Verified)”

Este trecho inclui apenas as linhas Verified da matriz de suporte de CSS auditada quanto à veracidade.

Módulo W3CNívelStatusEvidência
CSS Table (css_tables_3)3Verifiedsrc/Html/Table/, tests/Unit/Html/Table/ + testes do TableParser + PDFs golden
CSS Flexible Box Layout (css_flexbox_1)1Verifiedsrc/Html/Flex/, tests/Unit/Html/Flex/
CSS Grid Layout (css_grid_1)1Verifiedsrc/Html/Grid/, corpus WPT
CSS Cascading and Inheritance (css_cascade_3)3Verifiedsrc/Html/Cascade/

background-color, usado aqui para faixas alternadas nas linhas, é classificado como “Claimed” na matriz. Na auditoria da Phase 0, seu escopo é a célula da tabela. Ele é renderizado em linhas de tabela, mas não é listado como Verified.

Restrições de streaming de passagem única (ADR-001)

Seção intitulada “Restrições de streaming de passagem única (ADR-001)”

O buffer da tabela é a exceção documentada ao modelo de streaming. Ele tem vida curta e é limitado; não é um DOM geral. Não dependa de uma tabela para fornecer contexto de árvore ao conteúdo fora dela.

FormattingContextFactory::startTable() lê o CSS por meio do contrato da camada de layout. Ele não faz parsing direto de $css[...] bruto no caminho de despacho. A superfície pública continua sendo writeHtml().

Um contexto de formatação de tabela é limitado a 5,000 nós e 20 níveis de profundidade, dentro do teto de memória ativa de 50 MB (ADR-020). Divida ou pagine tabelas muito grandes. Não as renderize como um único contexto superdimensionado.

Marcações de tabela provenientes de entradas não confiáveis ficam sujeitas aos mesmos limites de elementos e aninhamento que o restante do HTML. Valide os dados de tabela criados a partir de entradas recebidas pela aplicação. O renderizador não executa conteúdo e, pela política padrão, não busca recursos remotos arbitrários.

DeclaraçãoEspecificaçãoCláusulareference_id
As larguras de coluna usadas são determinadas pelo algoritmo de dimensionamento de colunas da tabela na largura usada da tabela.W3C CSS Table Level 3css_tables_3#x1.x4.x9.x3
No modo fixo, o conteúdo da célula é ignorado no cálculo da largura da coluna.W3C CSS Table Level 3css_tables_3#x1.x4.x5.x1.p6

Esta receita mostra como o NextPDF renderiza tabelas HTML com suporte. O CSS Table Level 3 é Verified na matriz de suporte, e os demais módulos CSS usados aqui são classificados nessa matriz.

Não aplicável.