Управление документами
Управление документами
Document является точкой входа для каждой операции по управлению документами, рассматриваемой здесь: открытие и сохранение файлов, экспорт в HTML, добавление дополнительных слоёв содержания, создание Tagged PDF и чтение или запись данных AcroForm. Page и Form достигаются через Document.Page(n) и Document.Form().
Открытие и сохранение документов
pdf.Open загружает PDF из пути к файлу; pdf.OpenWithPassword делает то же самое для файлов, защищённых паролем. Document.Save записывает результат в новый путь к файлу.
doc, err := pdf.Open("input.pdf")
if err != nil {
panic(err)
}
_, err = pdf.OpenWithPassword("locked.pdf", "userpassword")
if err != nil {
panic(err)
}
err = doc.Save("output.pdf")Экспорт в HTML
Document.SaveHTML и Document.WriteHTML преобразуют документ в HTML. HTMLSaveOptions.Mode выбирает представление: HTMLModeText (видимый стилизованный текст поверх растрового фона без глифов), HTMLModeNative (графика страницы в виде одного встроенного SVG-слоя) или HTMLModeFlow (переполняемый HTML с заголовками и абзацами в порядке чтения). Оставление Mode без значения приводит к сохранению стандартного поведения: полностраничный растр с прозрачным выделяемым текстовым слоем.
doc, _ := pdf.Open("input.pdf")
// Faithful mode (default)
doc.SaveHTML("out.html")
// Visible-text mode
doc.SaveHTML("out.html", pdf.HTMLSaveOptions{Mode: pdf.HTMLModeText})
// Multi-file output: external resources plus one HTML file per page
doc.SaveHTML("site/doc.html", pdf.HTMLSaveOptions{
Mode: pdf.HTMLModeNative, ResourceDir: "assets", SplitPages: true,
})
// Page subset, custom raster DPI and title
doc.SaveHTML("part.html", pdf.HTMLSaveOptions{Pages: []int{1, 3}, DPI: 96, Title: "Report"})Управление дополнительными слоями содержания
Document.AddLayer(name) создает новую Optional Content Group и возвращает *Layer; Document.Layers() перечисляет все уже существующие слои. Page.BeginLayer / Page.EndLayer помечают содержимое страницы как принадлежащее слою, а Layer.SetVisible(false) скрывает это содержимое.
doc := pdf.NewDocumentFromFormat(pdf.PageFormatA4)
layer := doc.AddLayer("Watermark")
page, _ := doc.Page(1)
page.BeginLayer(layer)
page.AddText("DRAFT", pdf.TextStyle{Font: pdf.FontHelveticaBold, Size: 48},
pdf.Rectangle{LLX: 150, LLY: 400, URX: 450, URY: 460})
page.EndLayer()
layer.SetVisible(false)
doc.Save("layered.pdf")Создание тегированных (доступных) PDF
Document.TaggedContent() возвращает фасад *TaggedContent, который владеет логическим деревом структуры документа и устанавливает метаданные каталога, требуемые PDF/UA. Page.TagContent обрамляет вызов рисования в помеченном содержимом и возвращает *StructElement для этого узла.
doc := pdf.NewDocumentFromFormat(pdf.PageFormatA4)
tc := doc.TaggedContent()
tc.SetTitle("Quarterly Report")
tc.SetLanguage("en-US")
page, _ := doc.Page(1)
page.TagContent(tc.Root(), pdf.StructH1, func() error {
return page.AddText("Quarterly Report", pdf.TextStyle{Font: pdf.FontHelveticaBold, Size: 24},
pdf.Rectangle{LLX: 50, LLY: 760, URX: 545, URY: 800})
})
fig, _ := page.TagContent(tc.Root(), pdf.StructFigure, func() error {
return page.AddImage("chart.png", pdf.Rectangle{LLX: 50, LLY: 540, URX: 300, URY: 680})
})
fig.SetAlt("Bar chart of Q3 sales by region") // required for figures
doc.Save("accessible.pdf")Группирующие элементы также вложены под корень дерева:
doc := pdf.NewDocumentFromFormat(pdf.PageFormatA4)
tc := doc.TaggedContent()
page, _ := doc.Page(1)
tbl := tc.Root().AddChild(pdf.StructTable)
row := tbl.AddChild(pdf.StructTR)
cell := row.AddChild(pdf.StructTD)
page.TagContent(cell, pdf.StructP, func() error { return nil })Экспорт и импорт данных форм в виде JSON
Form.ExportJSON сериализует каждый тип поля и значение в JSON ({"name": {"type": "text", "value": "Jane"}, ...}); Form.ImportJSON применяет полезную нагрузку JSON к форме и возвращает количество полей, которые он обновил. JSONExportOptions.Indent форматирует вывод.
doc, _ := pdf.Open("filled.pdf")
data, _ := doc.Form().ExportJSON(pdf.JSONExportOptions{Indent: true})
// Fill a template from a JSON payload; discard the applied-field count.
template, _ := pdf.Open("template.pdf")
_, _ = template.Form().ImportJSON(data)Советы и лучшие практики
- Выберите
HTMLModeNativeдля страниц с большим количеством векторов,HTMLModeFlowдля перелистывания/мобильного чтения и надёжный вариант по умолчанию (без установленногоMode), когда важна визуальная точность. - Вызовите
Layer.SetVisible(false)передSave, чтобы по умолчанию скрыть слои водяных знаков или аннотаций, при этом сохраняя возможность адресации контента через объектLayer. - Установите
TaggedContent.SetTitleиSetLanguageперед вызовомPage.TagContent, поскольку проверка PDF/UA проверяет метаданные уровня каталога, которые записывают эти методы. - Вызовите
StructElement.SetAltна каждом узлеStructFigure— изображения без альтернативного текста не проходят проверку PDF/UA. - Используйте
JSONExportOptions.Indentдля удобочитаемого сравнения экспортированного состояния формы; опустите его для компактных машинных полезных нагрузок.
Распространённые проблемы
| Проблема | Причина | Исправление |
|---|---|---|
| HTML вывод не имеет выбираемых текстовых глифов | HTMLSaveOptions.Mode оставлен на верном значении по умолчанию без требования текстового слоя | Установите Mode: pdf.HTMLModeText для видимого, стилизованного текстового слоя |
| HTML экспорт теряет внешний вид исходного шрифта | NoFontEmbedding установлен в true | Оставьте NoFontEmbedding false (по умолчанию), чтобы встроенные шрифты были повторно упакованы как WOFF @font-face data URLs |
Page.TagContent возвращает ошибку | Вызвано до того, как Document.TaggedContent() инициализировал дерево структуры | Вызовите Document.TaggedContent() (и установите title/language) до первого вызова TagContent |
ValidatePDFUA сообщает о несоответствующих фигурах | Элемент StructFigure не имеет alt-текста | Вызовите StructElement.SetAlt для каждого узла figure |
Form.ImportJSON обновляет меньше полей, чем ожидалось | Имена полей полезной нагрузки JSON не совпадают с именами полей целевой формы; импорт работает снисходительно и пропускает несовпадающие записи | Подтвердите, что экспортированные имена полей точно соответствуют именам полей целевой формы |
FAQ
Какой режим экспорта HTML мне следует использовать?
HTMLModeText — для самого небольшого полностью выбранного вывода; HTMLModeNative — когда векторная точность (кривые, нативные штрихи) важнее размера файла; HTMLModeFlow — для перелистываемого, удобного для мобильных устройств макета чтения. Оставьте Mode неустановленным для верного по умолчанию raster-plus-transparent-text.
Могу ли я экспортировать только определённые страницы в HTML?
Да. Установите HTMLSaveOptions.Pages в срез номеров страниц, начинающихся с 1, например pdf.HTMLSaveOptions{Pages: []intpdf.HTMLSaveOptions{Pages: []intpdf.HTMLSaveOptions{Pages: []int{1, 3}}}}.
Как скрыть слой по умолчанию, но позволить просмотрщику включить его обратно?
Вызовите Layer.SetVisible(false) перед сохранением. Слой остаётся адресуемой Optional Content Group; Layer.IsVisible() сообщает его текущее состояние.
Включает ли экспорт формы JSON типы полей?
Да. Каждое экспортируемое поле представляет собой объект JSON с ключами type и value, например {"subscribe": {"type": "checkbox", "value": true}}.
Нужно ли вызывать TagContent для каждого элемента, или можно сразу вкладывать группы?
Оба варианта. Page.TagContent оборачивает вызов отрисовки и добавляет листовой элемент структуры. Для группировки элементов (таблицы, списки) вызовите StructElement.AddChild на корне дерева или родительском элементе, чтобы сначала построить вложенность, а затем пометьте листовое содержимое внутри.
API Reference Сводка
| Класс/Метод | Описание: |
|---|---|
Document.SaveHTML / WriteHTML | Экспортировать документ в HTML, контролируемый HTMLSaveOptions |
HTMLSaveOptions | HTML конфигурация экспорта: режим, DPI, подмножество страниц, обработка ресурсов |
Document.AddLayer / Layers | Создать или перечислить опциональные группы контента в документе |
Page.BeginLayer / EndLayer | Отметить содержимое страницы как принадлежащее слою |
Layer | Optional Content Group — имя и видимость |
Document.TaggedContent | Фасад для логического дерева структуры документа (Tagged PDF) |
TaggedContent | Устанавливает заголовок/язык документа и раскрывает корень дерева структуры |
Page.TagContent / TagArtifact | Вызовы рисования скобок в отмеченном содержимом и структурных элементах |
StructElement | Узел в логическом дереве структуры — дочерние элементы, альтернативный текст, язык |
Form.ExportJSON / ImportJSON | Сериализовать или применить данные поля AcroForm как JSON |
JSONExportOptions | JSON конфигурация экспорта: отступы, omit-empty |