Skip to content

PDF Acessível

Crie PDFs acessíveis que funcionam com leitores de tela e tecnologias assistivas usando estrutura com tags, texto alternativo e marcação de idioma.

O que Torna um PDF Acessível?

RequisitoPor Que É Importante
Tags de estruturaLeitores de tela usam tags de heading/parágrafo/lista para navegação
Texto alternativoDescreve imagens para usuários que não podem vê-las
Tag de idiomaInforma ao leitor como pronunciar o texto
Ordem de leituraOrdem lógica independente do layout visual
Cabeçalhos de tabelaAssocia células de dados ao contexto de coluna/linha
BookmarksNavegação por teclado para documentos longos

Padrões

PadrãoEscopo
PDF/UA-2 (ISO 14289-2)Acessibilidade Universal em PDF
WCAG 2.1Diretrizes de Acessibilidade para Conteúdo Web
Section 508Acessibilidade federal dos EUA
EN 301 549Requisitos de acessibilidade da UE

Exemplo de Código Completo

php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use TcpdfNext\Document;
use TcpdfNext\Enums\Alignment;
use TcpdfNext\Accessibility\TagManager;

// ── 1. Enable tagged PDF ───────────────────────────────────────────────
$pdf = Document::create()
    ->setTitle('Accessibility Report 2026')
    ->setAuthor('Acme Corp')
    ->setLanguage('en-US')
    ->setTagged(true)
    ->setDisplayDocTitle(true)
    ->addPage();

$tag = $pdf->getTagManager();

// ── 2. Heading (H1) ───────────────────────────────────────────────────
$tag->beginTag('H1');
$pdf->setFont('helvetica', style: 'B', size: 24)
    ->cell(0, 14, 'Accessibility Report 2026', newLine: true);
$tag->endTag();

// ── 3. Paragraph ──────────────────────────────────────────────────────
$tag->beginTag('P');
$pdf->setFont('times', size: 12)
    ->multiCell(0, 7, 'Acme Corp is committed to producing documents that '
        . 'meet PDF/UA and WCAG 2.1 AA standards, ensuring equal access '
        . 'for all users regardless of ability.');
$tag->endTag();

// ── 4. Sub-heading (H2) ──────────────────────────────────────────────
$tag->beginTag('H2');
$pdf->setFont('helvetica', style: 'B', size: 18)
    ->cell(0, 12, 'Key Metrics', newLine: true);
$tag->endTag();

// ── 5. Tagged list ────────────────────────────────────────────────────
$items = [
    'Documents audited: 1,240',
    'Compliance rate: 98.7%',
    'Issues resolved: 412',
];

$tag->beginTag('L');
foreach ($items as $item) {
    $tag->beginTag('LI');

    $tag->beginTag('Lbl');
    $pdf->setFont('helvetica', size: 11)
        ->cell(8, 7, "\u{2022}");
    $tag->endTag(); // Lbl

    $tag->beginTag('LBody');
    $pdf->cell(0, 7, $item, newLine: true);
    $tag->endTag(); // LBody

    $tag->endTag(); // LI
}
$tag->endTag(); // L

// ── 6. Image with alt text ────────────────────────────────────────────
$tag->beginTag('Figure');
$pdf->image(
    file:    __DIR__ . '/assets/compliance-chart.png',
    x:       null,
    y:       null,
    width:   120,
    height:  null,
    altText: 'Bar chart showing compliance rate rising from 91% in 2023 '
           . 'to 98.7% in 2026 across four consecutive years.',
);
$tag->beginTag('Caption');
$pdf->setFont('helvetica', style: 'I', size: 9)
    ->cell(0, 6, 'Figure 1: Compliance trend 2023-2026', newLine: true);
$tag->endTag(); // Caption
$tag->endTag(); // Figure

// ── 7. Decorative element as artifact (skipped by screen readers) ─────
$tag->beginArtifact('Layout');
$pdf->setDrawColor(200, 200, 200)
    ->line(15, $pdf->getY(), 195, $pdf->getY());
$tag->endArtifact();

// ── 8. Tagged table ───────────────────────────────────────────────────
$tag->beginTag('H2');
$pdf->setFont('helvetica', style: 'B', size: 18)
    ->cell(0, 12, 'Quarterly Results', newLine: true);
$tag->endTag();

$tag->beginTag('Table');

// Header row
$tag->beginTag('TR');
foreach (['Quarter', 'Audited', 'Passed', 'Rate'] as $header) {
    $tag->beginTag('TH', attributes: ['scope' => 'col']);
    $pdf->setFont('helvetica', style: 'B', size: 10)
        ->cell(45, 8, $header, border: 1);
    $tag->endTag();
}
$tag->endTag(); // TR

// Data rows
$rows = [
    ['Q1', '310', '305', '98.4%'],
    ['Q2', '320', '316', '98.8%'],
    ['Q3', '305', '302', '99.0%'],
    ['Q4', '305', '301', '98.7%'],
];
foreach ($rows as $row) {
    $tag->beginTag('TR');
    foreach ($row as $i => $cell) {
        $tagName = $i === 0 ? 'TH' : 'TD';
        $attrs   = $i === 0 ? ['scope' => 'row'] : [];
        $tag->beginTag($tagName, attributes: $attrs);
        $pdf->setFont('times', size: 10)
            ->cell(45, 8, $cell, border: 1);
        $tag->endTag();
    }
    $tag->endTag(); // TR
}
$tag->endTag(); // Table

// ── 9. Language tagging for foreign text ──────────────────────────────
$tag->beginTag('P', attributes: ['lang' => 'de-DE']);
$pdf->setFont('times', size: 11)
    ->multiCell(0, 7, 'Barrierefreiheit ist ein grundlegendes Recht.');
$tag->endTag();

// ── 10. Save ──────────────────────────────────────────────────────────
$pdf->save(__DIR__ . '/accessible-report.pdf');

echo 'Accessible PDF created.' . PHP_EOL;

Auto-Tagging HTML

O TCPDF-Next pode gerar tags de estrutura automaticamente a partir de HTML semântico:

php
$pdf = Document::create()
    ->setTagged(true)
    ->setLanguage('en-US')
    ->addPage();

$pdf->setAutoTagging(true)
    ->writeHtml(<<<'HTML'
        <h1>Report</h1>
        <p>Summary paragraph.</p>
        <img src="chart.png" alt="Revenue chart showing 15% growth" />
        <table>
            <tr><th>Q</th><th>Revenue</th></tr>
            <tr><td>Q1</td><td>$548M</td></tr>
        </table>
    HTML);
Elemento HTMLTag PDF
<h1>--<h6>H1--H6
<p>P
<img alt="...">Figure
<table>Table
<th>TH
<td>TD
<ul>, <ol>L
<li>LI
<a>Link

Checklist de Acessibilidade

  • [ ] setTitle() -- título do documento definido
  • [ ] setDisplayDocTitle(true) -- visualizador mostra o título, não o nome do arquivo
  • [ ] setLanguage('en-US') -- idioma do documento declarado
  • [ ] Todo conteúdo envolvido em tags de estrutura
  • [ ] Headings em ordem sequencial (H1, H2, H3 -- sem pular)
  • [ ] Todas as imagens significativas possuem altText
  • [ ] Imagens decorativas marcadas como artifacts
  • [ ] Tabelas possuem células TH com atributo scope
  • [ ] Ordem de leitura corresponde à ordem lógica
  • [ ] Relação de contraste de cor de pelo menos 4.5:1

Validação

bash
# Use PAC (PDF Accessibility Checker) for PDF/UA validation
# https://pdfua.foundation/en/pac-download/

Leitura Adicional

Distribuído sob a licença LGPL-3.0-or-later.