AcroForm 支持

概述

自 HotPDF v2.5.0 起,库可按照 PDF 1.7 ISO 32000-1 第 12.7 节输出交互式表单 (AcroForm)。每个表单字段都会创建为与字段字典合并的 Widget 批注,并自动注册到文档中,因此在 EndDoc 完成文档时,全局/AcroForm 条目会在 EndDoc 文档定稿时加入 Catalog。

支持的字段类型

  • 文本字段 (/FT /Tx) 通过 THPDFPage.AddTextField 创建。可通过 THPDFFormFieldFlags 启用单行、多行、密码、comb、文件选择、富文本、滚动和拼写检查选项
  • 复选框 (/FT /Btn,不含 Pushbutton/Radio 位) 通过 THPDFPage.AddCheckBox 创建,可配置导出值名称和初始选中状态
  • 单选按钮 (/FT /Btn /Ff Radio) 通过 THPDFPage.AddRadioButton 创建。多个同组名称的调用会合并到共享父字段下,并带有 /Kids 数组,符合 12.7.4.2 的要求
  • 组合框 (/FT /Ch /Ff Combo) 通过 THPDFPage.AddComboBox 创建,并传入开放数组形式的选项
  • 列表框 (/FT /Ch) 通过 THPDFPage.AddListBox 创建。ffMultiSelect 可启用多选
  • 按钮 (/FT /Btn /Ff Pushbutton) 通过 THPDFPage.AddPushButton 创建,可带可选标题 (/MK /CA)。自 HotPDF v2.31.0 起,THPDFPage.AddPushButtonWithAction 会把 PDF action 字典附加到 widget,使点击按钮时可运行 /SubmitForm、/ResetForm、/JavaScript 或 /URI;自 HotPDF v2.208.0 起,THPDFPage.AddPushButtonWithNextAction 可通过 /Next 串接第二个动作
  • 签名占位字段 (/FT /Sig) 自 HotPDF v2.12.0 起可通过 THPDFPage.AddSignatureField 创建。只要存在至少一个签名字段,AcroForm 字典就会自动获得 /SigFlags 3。该字段保持未签名,便于外部工具或专用 CMS / PKCS#7 签名库在保存文件后附加真实加密签名
  • 原地签名工作流 自 HotPDF v2.23.0 起通过 THPDFPage.AddSignedSignatureField、THotPDF.PreparePDFForSigning 和 THotPDF.InsertSignatureHex提供。第一次调用会预留带 /ByteRange 和 /Contents 占位符的 /V 签名字典。保存文档后,主机应用调用 PreparePDFForSigning 修补 /ByteRange 并取得待哈希的文件范围;外部生成 CMS / PKCS#7 detached signature 后,再调用 InsertSignatureHex 将签名十六进制写入占位符,不扰动文件中的其他字节

已加载表单字段的检查和更新

自 HotPDF v2.292.12 起,THPDFPage.CreateTextField、CreateCheckBox、CreateRadioButton、CreateComboBox 与 CreateListBox 辅助方法创建与既有 Add... 方法相同的 AcroForm 控件,并返回轻量的 THPDFAcroFormField 包装供立即配置

自 HotPDF v2.292.26 起,THotPDF.SetFormFieldTooltip 按字段名为经既有 Add... 方法创建的字段指定 PDF /TU 用户提示,与包装层的 THPDFAcroFormField.SetTooltip 工作流一致

自 HotPDF v2.298.0 起,创建期字段 API 与已加载文档字段创建 API 在注册任何控件之前,遇到重复根字段名即以诊断异常拒绝。相同组名的重复 AddRadioButton 调用仍然合法,因为它们共享一个父字段并在其 /Kids 数组下追加子控件

包装暴露链式 setter:/TU 提示、常见字段标志(SetReadOnly、SetRequired、SetNoExport)、/DA 默认外观字符串、字段级附加动作(如 /AA /K、/AA /F、/AA /V、/AA /C),以及经 THPDFActionBuilder

创建期包装 Pascal 示例

Field := HPDF.CurrentPage.CreateTextField('Email', '', Rect(50, 80, 250, 104));
Action := THPDFActionBuilder.JavaScript('event.rc = event.value.indexOf("@") > 0;');
try
  Field.SetTooltip('Email address');
  Field.SetRequired(True);
  Field.SetReadOnly(False);
  Field.SetAdditionalAction(fatValidate, Action);
finally
  Action.Free;
  Field.Free;
end;

已加载表单字段的检查与更新

自 HotPDF v2.121.9 起,应用可用 THotPDF.LoadFromFile 加载既有 AcroForm PDF,枚举字段,读取名称、类型与值,修改字段值,切换只读标志,并用 THotPDF.SaveLoadedDocument 保存已加载对象图。该路径面向对已加载文档的持久化编辑;不要只为保存已加载字段值变化而调用 BeginDoc / EndDoc。

字段辅助方法为 GetFormFieldCount、GetFormFieldName、GetFormFieldType、GetFormFieldValue、SetFormFieldValue 与 SetFormFieldReadOnly。字段查找接受从 0 开始的字段索引或完全限定字段名。返回的 THPDFLoadedFormFieldType 值为 lfftText、lfftButton、lfftChoice、lfftSignature 或 lfftUnknown。

已加载字段 Pascal 示例

HPDF.LoadFromFile('InputForm.pdf');
for I := 0 to HPDF.GetFormFieldCount - 1 do
  Writeln(HPDF.GetFormFieldName(I), ' = ', HPDF.GetFormFieldValue(I));

HPDF.SetFormFieldValue('CustomerName', 'Bob');
HPDF.SetFormFieldValue('Plan', 'Premium');
HPDF.SetFormFieldReadOnly('CustomerName', True);
HPDF.SaveLoadedDocument('UpdatedForm.pdf');

字段附加动作

这些包装AttachFieldKeyStrokeAction、AttachFieldFormatAction、AttachFieldValidateAction 和 AttachFieldCalculateAction 会把 JavaScript 附加到字段 /AA 字典,用于 PDF /K、/F、/V 和 /C触发器。同一触发器需要运行可复用动作链(JavaScript、ResetForm、SubmitForm、URI、Hide、ImportData 或链式 /Next 动作)时,使用 SetFormFieldAdditionalAction 或其命名的 THPDFActionBuilder 包装。控件级鼠标与焦点触发器也可按字段名经 SetFormFieldAnnotationAction 和命名的鼠标 / 焦点辅助方法安装;配套的 clear 辅助方法移除单个触发器,不影响 /AA 字典的其余部分

外观生成

默认情况下,输出的 /AcroForm 字典设置 /NeedAppearances true,把外观流渲染委托给消费端阅读器(Adobe Reader、Foxit、Chrome、浏览器、Apple Preview)。添加字段前把 THotPDF.AutoFormAppearances 设为 true,HotPDF 会为每个文本字段、按钮、choice(组合框 / 列表框)以及每个复选框 / 单选子控件的 Yes / Off 状态预生成 /AP /N Form XObject(PDF 1.7 8.10)。随后 AcroForm 字典携带 /NeedAppearances false,并带有引用标准 14 种基础字体(Helv Helvetica、ZaDb ZapfDingbats)的 /DR 默认资源条目,忽略 /NeedAppearances 的渲染器也能正确绘制字段内容。自 HotPDF v2.28.0 起可用。

字段标志参考 (THPDFFormFieldFlags)

  • ffReadOnly, ffRequired, ffNoExport — common Table 227 flags applicable to every field type.
  • ffMultiline, ffPassword, ffFileSelect, ffDoNotSpellCheck, ffDoNotScroll, ffComb, ffRichText — Tx-specific (Table 228).
  • ffEdit, ffSort, ffMultiSelect, ffDoNotSpellCheck, ffCommitOnSelChange — Ch-specific (Table 230).

Pascal 示例

HPDF.BeginDoc;
HPDF.AddPage;
HPDF.CurrentPage.AddTextField('Name', '', Rect(50, 100, 250, 120));
HPDF.CurrentPage.AddCheckBox('Agree', 'Yes', Rect(50, 130, 70, 145), True);
HPDF.CurrentPage.AddRadioButton('Color', 'Red',   Rect(50, 160, 70, 175), True);
HPDF.CurrentPage.AddRadioButton('Color', 'Green', Rect(80, 160, 100, 175));
HPDF.CurrentPage.AddRadioButton('Color', 'Blue',  Rect(110, 160, 130, 175));
HPDF.CurrentPage.AddComboBox('Country', 'CN',
                             ['CN', 'US', 'JP'], Rect(50, 190, 250, 210));
HPDF.EndDoc;

限制

  • AutoFormAppearances 生成器当前只排版 ASCII / WinAnsi 可编码值;/V 含多字节(UTF-8)文本的字段,其存储的 /AP 会渲染为空矩形,直到宿主阅读器重新生成外观。
  • 不生成 Down(/D)与 rollover(/R)子状态;只生成 normal(/N)状态。
  • 字段名唯一性由调用方责任;HotPDF 不强制执行

另请参阅