在企业信息化流程中,PDF 表单是一种常见的数据采集载体。用户填写完成后,系统往往需要自动提取表单域中的数据,用于入库、校验或后续业务处理。本文将介绍如何使用 C# 读取 PDF 文档中的交互式表单域,覆盖文本框、复选框、单选按钮组、下拉列表等常见字段类型。

一、方案概述

PDF 表单域的每个字段拥有唯一名称、类型标识和当前值。读取表单域的核心思路是:加载 PDF 文档 → 获取表单集合 → 遍历字段 → 根据字段类型提取对应值。

本文采用 Free Spire.PDF for .NET 免费库来完成读取操作。该库提供了 PdfFormWidget 类型用于操作 PDF 表单,支持通过索引或字段名定位具体字段。

二、环境准备

2.1 安装 NuGet 包

在 Visual Studio 的 NuGet 包管理器中搜索并安装 FreeSpire.PDF,或在包管理器控制台执行:

Install-Package FreeSpire.PDF

安装完成后,项目中会自动添加 Spire.Pdf.dll 引用。免费版对单个 PDF 文档有10页限制,对于表单读取场景通常足够使用。

2.2 引入命名空间

using Spire.Pdf;
using Spire.Pdf.Widget;
using System;
using System.Text;

三、读取 PDF 表单域的基本流程

3.1 加载 PDF 文档并获取表单

// 创建 PdfDocument 实例并加载 PDF 文件
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("YourForm.pdf");

// 获取文档中的表单(需转换为 PdfFormWidget 类型)
PdfFormWidget formWidget = doc.Form as PdfFormWidget;

需要注意的是,doc.Form 属性返回的是表单对象,但为了访问完整的字段集合,需要将其转换为 PdfFormWidget 类型

3.2 遍历所有表单域

通过 formWidget.FieldsWidget.List 可以获取所有表单域的集合:

// 遍历所有表单域
for (int i = 0; i < formWidget.FieldsWidget.List.Count; i++)
{
    PdfField field = formWidget.FieldsWidget.List[i] as PdfField;
    // 获取字段名称
    string fieldName = field.Name;
    Console.WriteLine($"字段名称: {fieldName}");
}

四、获取不同类型表单域的值

PDF 表单中常见的字段类型包括文本框、复选框、单选按钮、列表框和下拉列表框等。针对不同类型的字段,需要使用不同的属性来获取其值

4.1 文本框(PdfTextBoxFieldWidget)

文本框字段的值存储在 Text 属性中:

if (field is PdfTextBoxFieldWidget)
{
    PdfTextBoxFieldWidget textBoxField = field as PdfTextBoxFieldWidget;
    string name = textBoxField.Name;
    string value = textBoxField.Text;
    Console.WriteLine($"文本框 - 名称: {name}, 值: {value}");
}

4.2 复选框(PdfCheckBoxWidgetFieldWidget)

复选框的选中状态可通过 Checked 属性判断:

if (field is PdfCheckBoxWidgetFieldWidget)
{
    PdfCheckBoxWidgetFieldWidget checkBoxField = field as PdfCheckBoxWidgetFieldWidget;
    string name = checkBoxField.Name;
    bool isChecked = checkBoxField.Checked;
    Console.WriteLine($"复选框 - 名称: {name}, 是否选中: {isChecked}");
}

4.3 单选按钮组(PdfRadioButtonListFieldWidget)

单选按钮组中,可通过 SelectedValue 获取哪个选项被选中:

if (field is PdfRadioButtonListFieldWidget)
{
    PdfRadioButtonListFieldWidget radioBtnField = field as PdfRadioButtonListFieldWidget;
    string name = radioBtnField.Name;
    string selectedValue = radioBtnField.SelectedValue;
    Console.WriteLine($"单选按钮 - 名称: {name}, 选中值: {selectedValue}");;
}

4.4 列表框(PdfListBoxWidgetFieldWidget)

列表框的值包括所有可选项以及当前选中的项:

if (field is PdfListBoxWidgetFieldWidget)
{
    PdfListBoxWidgetFieldWidget listBoxField = field as PdfListBoxWidgetFieldWidget;
    string name = listBoxField.Name;
    string selectedValue = listBoxField.SelectedValue;

Console.WriteLine($"列表框 - 名称: {name}, 选中值: {selectedValue}");

// 获取所有选项
PdfListWidgetItemCollection items = listBoxField.Values;
foreach (PdfListWidgetItem item in items)
{
Console.WriteLine($" 选项: {item.Value}");
}
}

4.5 下拉列表(PdfComboBoxWidgetFieldWidget)

下拉列表框的取值方式与列表框类似:

if (field is PdfComboBoxWidgetFieldWidget)
{
    PdfComboBoxWidgetFieldWidget comboField = field as PdfComboBoxWidgetFieldWidget;
    string name = comboField.Name;
    string selectedValue = comboField.SelectedValue;
    Console.WriteLine($"下拉列表框 - 名称: {name}, 选中值: {selectedValue}");
}

五、注意事项与常见问题

5.1 空表单判断

并非所有 PDF 都包含表单。如果 doc.Form 无法转换为 PdfFormWidget,或 FieldsWidget.Count 为 0,说明文档不含交互式表单域,此时应走普通文本提取流程。

5.2 XFA 表单与 AcroForm 表单

PDF 表单主要有两种标准:

  • AcroForm:Adobe 原生表单标准,也是本文介绍的类型,对应 PdfFormWidget
  • XFA 表单:基于 XML 的表单规范,常见于旧版 Adobe LiveCycle 设计的表单

如果遇到 XFA 表单,需要通过 formWidget.XFAForm 另行处理,字段结构与取值方式完全不同。

5.3 资源释放

处理完 PDF 后,建议调用 doc.Close() 释放资源:

doc.Close();

六、总结

读取 PDF 表单域的核心在于正确识别字段类型并调用对应的取值属性。PdfFormWidget 提供了统一的字段访问入口,配合 as 模式匹配进行类型转换,即可覆盖绝大多数 AcroForm 表单的读取需求。

在实际项目中,建议先通过遍历方式摸清目标 PDF 的字段结构与命名规则,再封装为强类型的数据模型进行业务处理,这样既能保证读取的准确性,也便于后续维护扩展。