文档管理
Document 管理
Document 是每个 document-management 操作的入口点,涵盖以下内容:打开和保存文件,导出到 HTML,添加 optional content layers,创作 Tagged PDF,读取或写入 AcroForm data。Page 和 Form 通过 Document.Page(n) 和 Document.Form() 访问。
打开和保存 Documents
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 将 document 转换为 HTML. HTMLSaveOptions.Mode 选择 表示方式: HTMLModeText(可见的 样式化的 文本 在 无字形的 光栅 背景),HTMLModeNative(page 图形 作为 一个 内联 SVG 层),或 HTMLModeFlow(可重排的 HTML 带有 标题 和 段落 按阅读顺序)。如果 未 设置 Mode,将 产生 可信 的 默认值: 一个 完整 的 page raster 带有 透明 可选择 的 文本 层。
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"})管理 Optional Content Layers
Document.AddLayer(name) 创建一个新的可选内容组并返回一个 *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")构建 Tagged(可访问)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对象保持内容可寻址。 - 在调用
Page.TagContent之前,先设置TaggedContent.SetTitle和SetLanguage,因为 PDF/UA 验证会检查这些方法写入的目录级元数据。 - 对每个
StructFigure节点调用StructElement.SetAlt—— 没有替代文本的图形会导致 PDF/UA 验证失败。 - 在导出表单状态的可读差异比较时使用
JSONExportOptions.Indent;在紧凑的机器对机器负载中省略它。
常见问题
| 问题 | 原因 | 修复 |
|---|---|---|
| HTML 输出没有可选择的文本字形 | HTMLSaveOptions.Mode 保持忠实默认且没有文本层要求 | 设置 Mode: pdf.HTMLModeText 以实现可见的、样式化的文本层 |
| HTML 导出时丢失源字体外观 | NoFontEmbedding 设置为 true | 保留 NoFontEmbedding false(默认),以便嵌入的字体重新包装为 WOFF @font-face 数据 URL |
Page.TagContent 返回错误 | 在 Document.TaggedContent() 初始化结构树之前被调用 | 在第一次调用 TagContent 之前调用 Document.TaggedContent()(并设置标题/语言) |
ValidatePDFUA 报告不符合规范的图形 | 一个 StructFigure 元素没有 alt 文本 | 对每个图形节点调用 StructElement.SetAlt |
Form.ImportJSON 更新的字段少于预期 | JSON 负载字段名称与目标表单字段名称不匹配;导入过程宽松,会跳过不匹配的条目 | 确认导出的字段名称与目标表单字段名称完全匹配 |
FAQ
我应该使用哪种 HTML 导出模式?
HTMLModeText 用于最小且完全可选择的输出;HTMLModeNative 在矢量保真度(曲线、原生笔画)比文件大小更重要时使用;HTMLModeFlow 用于可重排、移动友好的阅读布局。将 Mode 保持未设置,以获得忠实的栅格加透明文本默认设置。
我可以只导出特定页面到HTML吗?
可以。将HTMLSaveOptions.Pages设置为基于1的页码切片,例如pdf.HTMLSaveOptions{Pages: []intpdf.HTMLSaveOptions{Pages: []intpdf.HTMLSaveOptions{Pages: []int{1, 3}}}}。
如何默认隐藏图层,但让查看器能够重新打开它?
在保存前调用Layer.SetVisible(false)。该图层仍保持为可寻址的可选内容组;Layer.IsVisible()报告其当前状态。
导出的JSON表单是否包含字段类型?
是的。每个导出的字段都是一个带有type和value键的JSON对象,例如{"subscribe": {"type": "checkbox", "value": true}}。
我需要为每个元素调用TagContent,还是可以直接嵌套组?
两者皆可。Page.TagContent包装一次绘制调用并添加一个叶子结构元素。对于分组元素(表格、列表),先在树根或父元素上调用StructElement.AddChild以构建嵌套,然后标记其下的叶子内容。
API Reference 摘要
| 类/方法 | 描述 |
|---|---|
Document.SaveHTML / WriteHTML | Export 文档到 HTML,由 HTMLSaveOptions 控制 |
HTMLSaveOptions | HTML export 配置:模式、DPI、页面子集、资源处理 |
Document.AddLayer / Layers | 在文档上创建或列出 Optional Content 组 |
Page.BeginLayer / EndLayer | 将页面内容标记为属于某个图层 |
Layer | 可选内容组 — 名称和可见性 |
Document.TaggedContent | 文档逻辑结构树的外观接口(Tagged PDF) |
TaggedContent | 设置文档标题/语言并公开结构树根节点 |
Page.TagContent / TagArtifact | 在标记内容和结构元素中的括号绘图调用 |
StructElement | 逻辑结构树中的节点 — 子节点,替代文本,语言 |
Form.ExportJSON / ImportJSON | 序列化或应用 AcroForm 字段数据为 JSON |
JSONExportOptions | JSON 导出配置:缩进,omit-empty |