文档管理

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 / WriteHTMLExport 文档到 HTML,由 HTMLSaveOptions 控制
HTMLSaveOptionsHTML 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
JSONExportOptionsJSON 导出配置:缩进,omit-empty

另请参阅

 中文