65.9K
CodeProject 正在变化。 阅读更多。
Home

从可填写的 PDF 文档中提取用户数据字段

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2019 年 6 月 19 日

CPOL

4分钟阅读

viewsIcon

18189

downloadIcon

1394

从可填写的 PDF 文档中提取用户数据的应用程序。它基于 PdfFileAnalyzer 项目(版本 2.1)。

引言

PDF 文档可以包含一组字段,用于收集用户的输入信息。这个项目允许您提取存储在这些字段中的数据。该项目依赖于 使用 C# 解析类的 PDF 文件分析器(版本 2.1)。该软件实现了 “PDF 参考,第六版,Adobe 可移植文档格式版本 1.7,2006 年 11 月” 的第 8.6 节交互式表单。

要提取数据字段,您需要提供一个 PDF 文件名。如果文件被加密,您需要提供密码。该库将打开文件并读取其主要结构。接下来,它将读取交互式数据字段。结果是一个包含字段名称和用户输入数据的字段数组。您可以将此数组序列化为 XML 文件。

执行 PDFExtractFormData 演示程序

启动程序。按“打开 PDF 文件”按钮。使用打开文件对话框打开包含交互式数据字段的 PDF 文件。演示程序将显示文档中的页数、间接对象的数量、文档中交互式数据字段的数量以及数字签名的数量。按“保存表单数据”,程序会将其保存到与 PDF 文件同名的 XML 文件中。XML 文件将由记事本显示。

将软件集成到您的应用程序

PdfFileAnalyzer.dll 库保存在您的开发区域中。将分发包中包含的三个源文件 PdfGetFormData.csPdfFieldData.csPdfFormData.cs 添加到您的项目中。将命名空间 PdfExtractFormData 添加到您的 using 列表中。添加对 PdfFileAnalyzer.dll 的引用。添加 using PdfFileAnalyzer 到您的源代码中。

创建一个 PDF 表单数据读取器。这是 PdfFileAnalyzerPdfReader 的派生类。

PdfGetFormData GetFormData = new PdfGetFormData();

打开 PDF 文件。

// open without a password
bool result = GetFormData.OpenPdfFile(PdfFileName);

// or, open with a password
bool result = GetFormData.OpenPdfFile(PdfFileName, Password);

除了加密错误之外,所有错误都会引发异常。如果文件已成功打开,则返回的结果为 true。如果文件受密码保护,并且未提供密码或密码错误,则结果为 false。检查属性 DecryptionStatus。如果它是 InvalidPassword 并且您知道密码,您可以使用 TestPassword 方法提供密码。请查看 PdfExtractFormData.cs 以获取完整的示例。

// set the password
bool Result = GetFormData.TestPassword(Password);

文件成功打开后,获取交互式数据字段。

// get form data
PdfFieldData[] FieldDataArray = GetFormData.GetFields();

如果 FieldDataArraynull,则 PDF 文件没有交互式数据字段。

PDF 文档表单数据存储在 PdfFieldData 元素的数组中。在 PDF 文档中,这些字段按层次结构组织。索引字段(从零开始)是进入 PdfFieldData 数组的索引。Parent 字段是当前字段的父字段的索引。-1 的 Parent 字段表示根字段。您可以从任何字段导航回根。

接下来的 4 个字段在 PDF 规范手册第 675 页表 8.69 中定义。如果字段类型 (Key=FT) 为空,则它不是数据字段,而是树层次结构的一部分。有 4 种类型的数据字段:Button (Btn)、Text (Tx)、Choice (Ch) 和 Signature (Sig)。每个字段都有一个名称 (Key=T) 和一个备用名称 (Key=TU) 和一个值 (Key=V)。名称和备用名称由 PDF 文档创建者分配。值由文档的用户输入。如果值为一个空 string,则用户未输入任何值。按钮和选项的值取自文档创建者分配的内置列表。用户从列表中选择值。如果一个选项字段具有多选功能,则所选选项将以换行符分隔。签名字段的处理方式与其他类型的字段不同。签名案例描述如下

public class PdfFieldData
    {
    public int Index;       // field index into the form array
    public int Parent;      // parent data field
    public string Type;     // Btn, Tx, Ch, Sig or empty
    public string Name;     // field name
    public string AltName;  // field alternate name
    public string Value;    // field value or empty
    }

如果字段 Type 是签名,则值字段为“Signature n”。其中 n 是签名在结果数组中的索引号。如果只有一个签名,则值为 Signature 0。并且该数组有一个元素。与所有签名字段相关的数据存储在 PDF 字典的数组中。

// get signature array
PdfDictionary[] Signatures = GetFormData.SignatureArray;
If(Signatures == null) {// there are no signatures}

// get the first signature information
PdfDictionary Signature = Signatures[0];

数字签名在 PDF 规范文档的第 8.7 节第 725 页中进行了描述。签名字典在第 727 页的表 8.102 中进行了详细说明。PdfFileAnalyzer 库允许您提取此字典中的任何条目。

保存第一个签名”按钮允许您以文本格式保存签名字典。它将被保存到与 PDF 文件同名的文件中,但扩展名为“.sig”。签名字典到文本的转换是通过以下方式完成的:

string Text = GetFormData.SigDictionary(index);

PdfGetFormData 提供了一种方法作为示例,说明如何从签名字典中提取数据。该示例展示了如何提取签名的加密字节数组。

byte[] Contents = GetFormData.SigContents(index);

历史

  • 2019/06/17:版本 1.0,原始版本
© . All rights reserved.