跳轉到

無障礙 PDF 指南

先決條件

composer require nextpdf/core

Tagged PDF 基礎

use NextPDF\Core\Accessibility\StructureTree;
use NextPDF\Core\Accessibility\StructureElement;
use NextPDF\Core\ValueObjects\Language;

$document = Document::createStandalone(
    pageSize: PageSize::A4,
)->withAccessibility(
    language: Language::fromBcp47('zh-TW'),
    title:    'NextPDF 無障礙文件範例',
    tagged:   true,
);

結構樹建立

$tree = $document->accessibility()->structureTree();

$root = $tree->root();

// 建立文件結構
$article = $root->appendSection(role: 'Article');

$heading = $article->appendHeading(
    level:     1,
    text:      '主要標題',
    lang:      'zh-TW',
);

$paragraph = $article->appendParagraph(
    text: '這是一個範例段落,包含完整的無障礙標記。',
    lang: 'zh-TW',
);

替代文字(Alt Text)

// 圖像的替代文字
$image = $document->images()->embed('/logo.png');

$figure = $article->appendFigure(
    altText:     'NextPDF 公司標誌,藍色底色白色文字',
    actualText:  'NextPDF',
);

$document->drawing()->image(
    image:           $image,
    x:               25.0,
    y:               20.0,
    width:           50.0,
    structureElement: $figure,
);

// 裝飾性元素(不需替代文字)
$document->drawing()->decorativeLine(
    x1: 25.0, y1: 30.0,
    x2: 185.0, y2: 30.0,
    artifact: true,  // 標記為 Artifact,螢幕閱讀器忽略
);

閱讀順序

// 明確設定 Tab 順序(多欄版面必須)
$document->accessibility()->setTabOrder(
    order: ['column-1-content', 'column-2-content'],
);

表格無障礙

$table = $article->appendTable(
    summary: '年度銷售數據,第一欄為月份,其餘欄為各地區銷售額',
);

$thead = $table->appendTableHead();
$row   = $thead->appendRow();
$row->appendHeaderCell(text: '月份', scope: 'col');
$row->appendHeaderCell(text: '台灣', scope: 'col');
$row->appendHeaderCell(text: '日本', scope: 'col');

$tbody = $table->appendTableBody();
$dataRow = $tbody->appendRow();
$dataRow->appendHeaderCell(text: '一月', scope: 'row');
$dataRow->appendDataCell(text: 'NT$ 1,200,000');
$dataRow->appendDataCell(text: '¥ 3,500,000');

表單無障礙

$forms->addTextField(
    field: TextField::create(
        name:        'customer_name',
        label:       '客戶姓名',
        tooltip:     '請輸入完整姓名,例如:王小明',
        required:    true,
        ariaLabel:   '客戶姓名(必填)',
    ),
    bounds: Rectangle::create(x: 25.0, y: 80.0, width: 120.0, height: 15.0),
);

語言設定

// 文件語言
$document->withAccessibility(language: Language::fromBcp47('zh-TW'));

// 段落內的異語言引用
$paragraph = $article->appendParagraph(text: '');
$paragraph->appendSpan(text: 'PDF/UA', lang: 'en');
$paragraph->appendSpan(text: ' 是無障礙 PDF 的國際標準。', lang: 'zh-TW');

WCAG 合規檢查

use NextPDF\Core\Accessibility\WcagChecker;
use NextPDF\Core\Accessibility\ComplianceLevel;

$checker = WcagChecker::create();
$report  = $checker->check(
    document: $document,
    level:    ComplianceLevel::AA,
);

if (!$report->passed()) {
    foreach ($report->violations() as $violation) {
        echo "WCAG {$violation->criterion()}: {$violation->message()}\n";
    }
}

PDF/UA-2 驗證

use NextPDF\Core\Accessibility\PdfUaValidator;

$validator = PdfUaValidator::create();
$result    = $validator->validate(document: $document);

$result->conformanceLevel();  // 'PDF/UA-2'
$result->passed();            // bool
$result->failures();          // list<ValidationFailure>

PDF/A + PDF/UA 雙重合規

延伸閱讀