Structure
Structure
Эта страница охватывает навигацию по документу и логическую структуру: оглавления (закладки), таблицы содержимого, именованные назначения и помеченное дерево структуры, используемое для доступности и перераспределения.
Оглавления (закладки)
Document.GetOutlines() возвращает текущее дерево оглавления как OutlineItem[] ([], когда нет /Outlines); Document.SetOutlines() заменяет его — передача [] полностью удаляет оглавление. Каждый OutlineItem имеет Title, Dest (номер страницы или именованное назначение), необязательный Children для вложенности и стилизацию (Color, Bold, Italic, Open).
const items: OutlineItem[] = sections.map((s) => {
const item: OutlineItem = { Title: s.title, Dest: { name: s.dest } };
if (s.subtype === 'sales') {
item.Open = true;
item.Children = ['Pasta', 'Pizza', 'Antipasti']
.map((cat) => ({ Title: cat, Dest: { name: s.dest } }));
}
return item;
});
doc.SetOutlines(items);Оглавление
Page.AddTOC() отображает список объектов TOCEntry — каждый с title и целевым номером page — в прямоугольнике на странице, с переносом заголовков, точечными лидерами и выровненными по правому краю метками страниц. Он возвращает AddTOCResult, сообщающий, сколько записей было отрисовано, и, если коробка слишком мала, remainder, которые не поместились.
page.AddTOC(
sections.map((s, i) => ({ title: `${i + 1}. ${s.title}`, page: s.page.Number })),
[72, 160, 400, 400],
{ font: 'Helvetica', fontSize: 13, rowGap: 18 },
);Именованные назначения
Document.GetNamedDestinations() возвращает каждое именованное назначение — объединяя дерево имён /Names /Dests и наследующий словарь /Dests — в виде пар { name, dest }, где dest является PageDest ({ page, view }). Это те же именованные цели, которые OutlineItem.Dest или аннотация ссылки могут ссылаться по имени вместо явного номера страницы.
const destNames = new Set(doc.GetNamedDestinations().map((d) => d.name));
for (const { name, dest } of doc.GetNamedDestinations()) {
console.log(name, '-> page', dest.page);
}Дерево помеченной структуры
Document.AutoTag() выводит и создает /StructTreeRoot из макета страницы — заголовки по кластеризации размеров шрифта, абзацы по блокам текста, таблицы по геометрии линий, а для каждого изображения — решения /Figure vs. /Artifact — и возвращает AutoTagReport с подсчётами для каждого типа элемента. Document.GetStructTree() считывает полученный StructTreeRoot, или null, если документ не помечен.
const report = doc.AutoTag({ lang: 'en-US', title: 'Quarterly Report', tables: true });
console.log(report.headings, report.paragraphs, report.tables, report.figures);
const tree = doc.GetStructTree();
console.log(tree ? tree.GetText() : '(no structure tree)');Содержимое, добавленное после выполнения AutoTag() — например, страница, заполненная позже — не охватывается этим проходом и не будет двойного помечания. StructTreeRoot.Append() и StructElement.MarkContent() представляют собой ручные API авторства наряду с эвристическим: Append() добавляет дочерний элемент заданного типа, а MarkContent() отмечает область страницы как принадлежащую этому элементу.
Советы и лучшие практики
- Запустите
Document.AutoTag()один раз, после того как содержимое страницы окончательно — он не пере-помечает добавленное позже содержимое, поэтому вручную пометьте всё, что добавлено позже, с помощьюStructTreeRoot.Append()/StructElement.MarkContent(). - Передайте
opts.titleвAutoTag()— это также устанавливает/ViewerPreferences /DisplayDocTitle, которое PDF/UA требует вместе с заголовком документа. OutlineItem.Destможет указывать либо на явную страницу, либо на именованное назначение ({ name: '...' }) — используйте именованные назначения, когда номер целевой страницы может измениться при изменении содержимого.- Проверьте
AddTOCResult.remainder, когда автопагинация отключена — поле оглавления, слишком маленькое для каждой записи, тихо прекращает отрисовку вместо переполнения поля.
Распространённые проблемы
| Проблема | Причина | Исправление |
|---|---|---|
Document.GetStructTree() возвращает null | Документ не был помечен | Сначала вызовите Document.AutoTag() или Document.CreateStructTree() |
| Ссылка элемента оглавления не разрешается | Её Dest указывает на пункт назначения, которого нет в Document.GetNamedDestinations() | Подтвердите, что указанное назначение существует, или используйте вместо этого явную страницу Dest |
Page.AddTOC() останавливается перед последним разделом | Целевой rect слишком мал для каждой записи, а autoPaginate отключён | Увеличьте rect, передайте autoPaginate: true или обработайте AddTOCResult.remainder |
Содержимое, добавленное после AutoTag(), отсутствует в дереве структуры | AutoTag() только отмечает содержимое, присутствующее в момент его выполнения | Ручным образом пометьте последующее содержимое с помощью StructTreeRoot.Append() / StructElement.MarkContent() |
FAQ
Как добавить закладки в PDF?
Создайте массив объектов OutlineItem (Title, Dest, опциональный Children) и передайте его в Document.SetOutlines().
Может ли оглавление растягиваться на несколько страниц?
Да — передайте autoPaginate: true в опциях Page.AddTOC(), либо проверьте AddTOCResult.remainder и вызовите AddTOC() снова на новой странице для того, что не поместилось.
Как сделать PDF доступным (с тегами)?
Вызовите Document.AutoTag(), который выводит заголовки, абзацы, таблицы и рисунки из макета страницы. Для добавленного позже контента или когда результат эвристики требует исправления, используйте непосредственно StructTreeRoot.Append() и StructElement.MarkContent() напрямую.
В чём разница между назначением по номеру страницы и именованным назначением?
Назначение по номеру страницы (PageDest) указывает на конкретную страницу, нумерация которой начинается с 1. Именованное назначение (NamedDest) указывает на имя, которое просмотрщик разрешает с помощью таблиц именованных назначений документа — полезно, когда целевая страница может переместиться.
API Reference Сводка
| Класс/Метод | Описание: |
|---|---|
Document.GetOutlines() / Document.SetOutlines() | Читать или заменять дерево оглавления (закладки) документа |
OutlineItem | Один узел оглавления: Title, Dest, необязательный Children |
Page.AddTOC() | Отрисовать оглавление в прямоугольнике страницы |
TOCEntry / AddTOCResult | Данные строки TOC и результат её отрисовки |
Document.GetNamedDestinations() | Перечислите все именованные назначения в документе |
Document.AutoTag() | Сформируйте и создайте теговое дерево структуры на основе макета страницы |
Document.GetStructTree() / Document.CreateStructTree() | Прочитайте или создайте StructTreeRoot документа |
StructTreeRoot.Append() / StructElement.Append() / StructElement.MarkContent() | Вручную создайте или расширьте дерево структуры |