C# 填写 PDF 交互式表单:文本框、复选框、单选按钮和下拉列表

在开发员工登记、业务申请或信息采集系统时,经常需要将用户提交的数据自动填写到已有的 PDF 表单中。

如果 PDF 包含交互式表单字段(AcroForm),就可以通过 C# 直接修改字段内容,而不需要计算文字在页面上的坐标。常见的表单字段包括文本框、单选按钮、复选框、下拉框和列表框。

本文以一份员工信息登记表为例,介绍如何使用 C# 读取并填写不同类型的 PDF 表单字段,最后保存为新的 PDF 文件。

一、安装 PDF 处理库

本文使用免费版 Free Spire.PDF for .NET。

在 Visual Studio 中打开"工具 → NuGet 包管理器 → 程序包管理器控制台",执行:

复制代码
Install-Package FreeSpire.PDF -Version 12.4.0

也可以通过 .NET CLI 安装:

lua 复制代码
dotnet add package FreeSpire.PDF --version 12.4.0

免费版对处理的 PDF 有 10 页限制,因此建议使用不超过 10 页的表单模板。

二、C# 填写 PDF 交互式表单的实现步骤

假设已有一份名为 ​​员工信息登记表.pdf​​ 的 PDF 文件,其中包含以下表单字段:

表单字段 字段类型 填写内容
姓名 文本框 李晓雯
联系地址 文本框 上海市浦东新区
性别 单选按钮 女
同意条款 复选框 勾选
所属部门 下拉框 技术部
兴趣爱好 列表框 摄影

接下来按照加载 PDF、获取字段、填写内容和保存文件的顺序进行操作。

步骤 1:导入命名空间

首先导入 PDF 文档处理、表单字段操作和字体设置所需的命名空间:

sql 复制代码
using System;
using Spire.Pdf;
using Spire.Pdf.Fields;
using Spire.Pdf.Widget;
using Spire.Pdf.Graphics;

其中,​​Spire.Pdf.Widget​​ 命名空间包含用于操作已有 PDF 表单字段的相关类型,包括文本框、复选框、单选按钮等控件。

步骤 2:加载 PDF 并获取表单字段

创建 ​​PdfDocument​​ 对象,通过 ​​LoadFromFile()​​ 加载 PDF 模板,再获取交互式表单及其字段集合。

ini 复制代码
// 加载 PDF 表单模板
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("员工信息登记表.pdf");

// 获取交互式表单
PdfFormWidget form = pdf.Form as PdfFormWidget;

// 获取表单字段集合
PdfFormFieldWidgetCollection fields = form.FieldsWidget;

​​FieldsWidget​​ 包含 PDF 中已有的交互式表单字段,可以通过索引逐一访问。

需要注意的是,PDF 页面上显示的字段标签,不一定与字段内部名称相同 。例如,页面上标注"姓名",但对应的字段名称可能是 ​​name​​、​​Text1​​ 或其他内容。

后续代码需要根据字段的实际名称进行匹配。如果使用自己的 PDF 模板,应先确认字段名称是否一致。

以上代码假设文件中包含 AcroForm 字段。完整示例还会加入空值检查,避免表单不存在时发生异常。

步骤 3:遍历并填写表单字段

不同类型的表单控件,需要通过不同的属性设置内容。

表单字段类型 设置属性 示例
文本框 ​​PdfTextBoxFieldWidget​​ ​​Text​​ ​​textBox.Text = "李晓雯";​​
单选按钮 ​​PdfRadioButtonListFieldWidget​​ ​​SelectedIndex​​ ​​radio.SelectedIndex = 1;​​
复选框 ​​PdfCheckBoxWidgetFieldWidget​​ ​​Checked​​ ​​checkBox.Checked = true;​​
下拉框 ​​PdfComboBoxWidgetFieldWidget​​ ​​SelectedIndex​​ ​​comboBox.SelectedIndex = new int[] { 1 };​​
列表框 ​​PdfListBoxWidgetFieldWidget​​ ​​SelectedIndex​​ ​​listBox.SelectedIndex = new int[] { 0 };​​

例如,要向名称为"姓名"的文本框填写内容,可以通过 ​​for​​ 循环遍历字段,判断字段类型和名称后再赋值:

ini 复制代码
for (int i = 0; i < fields.Count; i++)
{
    PdfField field = fields[i];

    if (field is PdfTextBoxFieldWidget textBox &&
        field.Name == "姓名")
    {
        textBox.Text = "李晓雯";
    }
}

对于单选按钮、下拉框和列表框,需要特别注意选项索引的设置:

  • 索引从 0 开始。 例如,SelectedIndex = 1 表示选择第二个选项。
  • 属性类型有所不同。 单选按钮使用整数索引,而下拉框和列表框使用 int[] 整数数组。

此外,填写中文时还需要考虑字体支持。如果原始文本框使用的字体不支持汉字,即使程序成功赋值,生成的 PDF 也可能显示为空白或乱码。完整示例中会为文本框设置支持中文的字体。

步骤 4:保存填写后的 PDF

字段填写完成后,调用 ​​SaveToFile()​​ 保存 PDF,并通过 ​​Close()​​ 关闭文档。

scss 复制代码
// 保存填写后的 PDF
pdf.SaveToFile("员工信息登记表_已填写.pdf", FileFormat.PDF);

// 关闭文档
pdf.Close();

这里使用新的输出文件名,避免覆盖原始表单模板。

保存后的 PDF 仍然保留交互式字段,可以在支持 AcroForm 的 PDF 阅读器中继续填写或修改。

三、完整 C# 代码示例

下面通过一段完整代码,演示如何在同一份 PDF 中填写文本框、单选按钮、复选框、下拉框和列表框。

假设 PDF 表单中的字段名称与前文表格一致,并且选项顺序如下:

  • 性别: 男、女
  • 所属部门: 行政部、技术部、市场部
  • 兴趣爱好: 摄影、阅读、旅行
ini 复制代码
using System;
using Spire.Pdf;
using Spire.Pdf.Fields;
using Spire.Pdf.Widget;
using Spire.Pdf.Graphics;

class Program
{
    static void Main()
    {
        PdfDocument pdf = new PdfDocument();

        try
        {
            // 加载 PDF 表单模板
            pdf.LoadFromFile("员工信息登记表.pdf");

            // 获取交互式表单
            PdfFormWidget form = pdf.Form as PdfFormWidget;

            if (form == null || form.FieldsWidget.Count == 0)
            {
                Console.WriteLine("PDF 中没有可填写的表单字段。");
                return;
            }

            PdfFormFieldWidgetCollection fields = form.FieldsWidget;

            // 创建支持中文的字体(Windows 环境)
            PdfTrueTypeFont chineseFont = new PdfTrueTypeFont(
                new System.Drawing.Font("Microsoft YaHei", 11),
                true
            );

            // 遍历所有表单字段
            for (int i = 0; i < fields.Count; i++)
            {
                PdfField field = fields[i];

                // 填写文本框
                if (field is PdfTextBoxFieldWidget textBox)
                {
                    switch (field.Name)
                    {
                        case "姓名":
                            textBox.Font = chineseFont;
                            textBox.Text = "李晓雯";
                            break;

                        case "联系地址":
                            textBox.Font = chineseFont;
                            textBox.Text = "上海市浦东新区";
                            break;
                    }
                }

                // 设置单选按钮
                else if (field is PdfRadioButtonListFieldWidget radio)
                {
                    if (field.Name == "性别")
                    {
                        // 选择第二项:女
                        radio.SelectedIndex = 1;
                    }
                }

                // 勾选复选框
                else if (field is PdfCheckBoxWidgetFieldWidget checkBox)
                {
                    if (field.Name == "同意条款")
                    {
                        checkBox.Checked = true;
                    }
                }

                // 设置下拉框
                else if (field is PdfComboBoxWidgetFieldWidget comboBox)
                {
                    if (field.Name == "所属部门")
                    {
                        // 选择第二项:技术部
                        comboBox.SelectedIndex = new int[] { 1 };
                    }
                }

                // 设置列表框
                else if (field is PdfListBoxWidgetFieldWidget listBox)
                {
                    if (field.Name == "兴趣爱好")
                    {
                        // 选择第一项:摄影
                        listBox.SelectedIndex = new int[] { 0 };
                    }
                }
            }

            // 保存填写后的 PDF
            pdf.SaveToFile("员工信息登记表_已填写.pdf", FileFormat.PDF);

            Console.WriteLine("PDF 表单填写完成。");
        }
        finally
        {
            pdf.Close();
        }
    }
}

运行程序后,会生成 ​​员工信息登记表_已填写.pdf​​,其中包含填写好的姓名、联系地址以及各类表单选项。

需要注意,代码中的字段名称和选项索引必须与实际 PDF 模板一致。如果表单来自其他系统,应根据其内部字段名称和选项顺序调整代码。

另外,本例使用 Windows 系统中的微软雅黑(Microsoft YaHei)字体。如果运行环境中没有该字体,需要替换为其他支持中文的字体。

四、C# 填写 PDF 表单时的常见问题

1. 程序运行成功,但 PDF 中没有填入内容

这种情况通常是因为代码中的字段名称与 PDF 实际字段名称不一致。

可以通过以下代码输出表单中所有字段的名称和类型:

ini 复制代码
for (int i = 0; i < fields.Count; i++)
{
    PdfField field = fields[i];

    Console.WriteLine(
        $"{field.Name} - {field.GetType().Name}"
    );
}

根据输出结果检查代码中的 ​​field.Name​​ 判断条件。字段名称通常需要严格匹配,包括大小写和空格。

2. 填写中文后出现乱码或内容不显示

首先检查文本框使用的字体是否支持中文。

例如,某些 PDF 模板默认使用的西文字体没有中文字形,直接填写中文可能导致显示异常。

可以尝试为文本框指定支持中文的字体:

ini 复制代码
textBox.Font = new PdfTrueTypeFont(
    new System.Drawing.Font("Microsoft YaHei", 11),
    true
);

textBox.Text = "李晓雯";

此代码需要导入 ​​Spire.Pdf.Graphics​​ 命名空间,并确保运行环境中安装了对应字体。

如果仍然显示异常,还应检查文本框的外观设置,并尝试使用其他 PDF 阅读器打开生成的文件,排除阅读器渲染差异。

3. 单选按钮或下拉框选中了错误的选项

通常是因为设置的索引与实际选项顺序不一致。

例如:

ini 复制代码
radio.SelectedIndex = 1;

这表示选中第二个单选按钮,并不意味着一定选择"女"。

不同 PDF 模板可能采用不同的选项顺序。填写前应先确认各个选项对应的索引,避免出现内容与预期不符的情况。

4. PDF 中有输入框,但程序无法获取表单字段

并不是所有看起来像表单的 PDF 都包含可交互字段。

常见情况包括:

  • PDF 只是普通文档,页面上的输入区域由线条和矩形组成。
  • 文件是扫描件,输入区域实际上是图片的一部分。
  • PDF 表单已经被扁平化,原来的交互式字段不再存在。
  • 文件使用 XFA 等其他表单结构,而不是普通 AcroForm。

如果无法获取表单字段,建议先检查 PDF 的实际结构,确认它是否包含可通过 ​​FieldsWidget​​ 访问的 AcroForm 字段。

总结

使用 C# 填写 PDF 交互式表单,主要是通过 ​​FieldsWidget​​ 获取表单字段,根据字段名称和类型设置对应内容,再将结果保存为新的 PDF 文件。

这种方式适合员工登记、业务申请等使用固定 PDF 模板的场景。在实际项目中,还可以将示例中的固定值替换为数据库记录或用户提交的数据,实现 PDF 表单的自动填写,减少重复的人工录入工作。

相关推荐
IT枫斗者枫哥19 分钟前
Java 退款请求超时,先查原单还是重试?
java·后端
特立独行的猫A23 分钟前
我用仓颉写了个多平台发文工具:一份 Markdown,一条命令发六个平台
java·后端·python
ikgy36 分钟前
JAVA EE:1.计算机是如何工作的
java·java-ee
.痞老板.1 小时前
java ee--计算机是如何工作的
java·开发语言·java-ee
青梅味猪大肠1 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统
CoderYanger1 小时前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)
java·数据库·spring·面试·职场和发展·java-ee·mybatis
程序员沉梦听雨2 小时前
【搜索引擎】Kibana使用指南
java·后端·学习笔记
奶油话梅糖3 小时前
打开项目 0.9 秒、内存只有 IDEA 的 1/12:OpenIDEA 用 Rust 把 IntelliJ IDEA 重造了一遍
java·rust·github·intellij-idea
vipxieliang3 小时前
语言对比卡:PHP vs Go vs Java 的优缺点、适用场景与「为什么选 PHP」
java·go·php