C# 中的 PDF 表單:建立、填寫和處理互動式表單

This article was translated from English: Does it need improvement?
Translated
View the article in English

使用 IronPDF 的C# .NET中的PDF AcroForms為開發人員提供了互動式表單欄位的完全程式控制,從讀取和填寫現有的政府表格到從 HTML 建立新表格、提取提交的資料以及批次處理數千份文件。 IronPDF 可以處理所有標準字段類型,包括文字輸入、複選框、單選按鈕、下拉列表和簽名字段,讓您使用現有的 HTML 和 CSS 技能自動執行完整的PDF 表單生命週期

TL;DR:快速入門指南

本教學涵蓋了在 C# .NET 中建立、填寫和處理互動式 PDF 表單,從讀取現有表單欄位到批次產生已完成的文件。

-適用對象:為政府、醫療保健、金融或人力資源流程自動化 PDF 表單工作流程的 .NET 開發人員。 -你將建立的功能:讀取並填寫 PDF 表單(文字、複選框、單選按鈕、下拉清單),從 HTML建立 PDF 表單,提取提交的數據,驗證輸入,將表單展平以鎖定值,自動處理 W-9 表格,並批量產生已完成的表單。 -運行環境: .NET 10、.NET 8 LTS、.NET Framework 4.6.2+ 和 .NET Standard 2.0。輸出檔案可在 Adobe Acrobat、預覽和所有主流 PDF 閱讀器中開啟。 -何時使用此方法:當您的應用程式需要大規模填寫、建立或處理 PDF 表單而無需手動輸入資料。 -從技術角度來看,這很重要: AcroForm 欄位是結構化對象,可以透過程式設計方式進行可預測的讀取和寫入。 IronPDF 也將 HTML 表單元素轉換為其對應的 AcroForm 元素,以實現充分的設計彈性。

只需幾行程式碼即可填寫您的第一個 PDF 表單:

Nuget Icon立即開始使用 NuGet 建立 PDF 檔案:

  1. 使用 NuGet 套件管理器安裝 IronPDF

    PM > Install-Package IronPdf

  2. 複製並運行這段程式碼。

    var pdf = IronPdf.PdfDocument.FromFile("form.pdf");
    pdf.Form.FindFormField("name").Value = "John Smith";
    pdf.SaveAs("filled-form.pdf");
  3. 部署到您的生產環境進行測試

    立即開始在您的專案中使用 IronPDF,免費試用!
    arrow pointer

購買或註冊 IronPDF 的 30 天試用版後,請在應用程式開始時新增您的授權金鑰。

IronPdf.License.LicenseKey = "KEY";
IronPdf.License.LicenseKey = "KEY";
Imports IronPdf

IronPdf.License.LicenseKey = "KEY"
$vbLabelText   $csharpLabel

!{--01001100010010010100001001010010010000010101001001011001010111110101001101010100010001010101010 10100010111110101010001010010010010010100000101001100010111110100001001001100010011111010000100100110001001111010101 !{--010011000100100101000010010100100100000101010010010110010101111101001110010101010101010101010101010101010101010 0100010111110100100101001101010100010000010100110001001100010111110100001001001100010011110010101010

as-heading:2(目錄)

為什麼互動式 PDF 表單在 2025 年仍然至關重要?

儘管網頁表單和基於雲端的文件解決方案層出不窮,但 PDF 表單仍然在關鍵業務流程中佔據主導地位。 政府機構、醫療機構、金融機構和律師事務所都大量使用 PDF 表格作為官方文件。 僅在醫療保健領域,88% 的患者記錄就是以 PDF 格式儲存或共享的。 全球稅務機關每年處理數十億份表格提交,其中絕大多數是以電子 PDF 文件的形式提交的。

既然有看似更現代的替代方案,為什麼這種格式仍然沿用?答案在於法律要求、通用相容性和文件完整性等因素的綜合考慮。 PDF 表單無論使用何種裝置或作業系統查看,都能保持精確的格式。 在Windows桌上型電腦上填寫的表格,無論是在Mac筆記型電腦上開啟或在政府部門列印,其顯示效果都完全相同。這種一致性在處理法律文件、監管備案和官方記錄時至關重要,因為精確的格式會影響文件的有效性。

網頁表單固然有其用武之地,但由於多種原因,它們無法完全取代 PDF 表單。 許多監管機構明確要求提交PDF格式的文件。 法律訴訟通常要求文件採用能夠可靠存檔並在多年後進行核實的格式。 對於現場工作人員、偏遠地區以及無法保證網路連線的情況,離線存取仍然非常重要。 此外,PDF 表格可以進行數位簽名、加密和跟踪,從而提供合規性所需的審計追蹤。

PDF軟體市場反映了這種持續的需求,2024年市場規模達到48億美元,預計到2030年將以每年8%至11%的速度成長。對.NET開發人員來說,這既是技術挑戰,也是重大機會。 掌握 PDF 表單自動化意味著能夠簡化涉及各行各業數百萬份文件的工作流程。


什麼是 PDF AcroForms?它們是如何運作的?

AcroForms 是 PDF 規格中內建的標準互動式表單技術。 AcroForms 由 Adobe 開發,現在作為 ISO 標準進行維護,它允許 PDF 文件包含可填寫字段,用戶可以使用任何相容的 PDF 閱讀器完成填寫。 當您在 Adobe Acrobat 或 Preview 中開啟稅務表格並在欄位中輸入內容時,您實際上是在與嵌入該文件中的 AcroForm 元素進行互動。

AcroForm 中的每個表單欄位都具有幾個關鍵屬性。 欄位名稱是程式用來定位和操作該欄位的唯一識別碼。 欄位類型決定了欄位接受的輸入類型,可以是文字、複選框、單選按鈕、下拉選擇或簽名。 value 屬性保存欄位的目前內容,可以透過程式設計方式讀取或寫入。 其他屬性控制外觀、驗證規則和預設值。

AcroForms 支援多種不同的欄位類型,可滿足大多數資料收集需求。 文字欄位接受自由格式的文字輸入,可以配置為單行或多行。 複選框字段表示二元選擇,可以分組以允許多選。 單選按鈕欄位以群組的形式協同工作,選擇一個選項會自動取消選擇其他選項。 組合框和列錶框提供預先定義的選項供選擇。 簽章欄為數位簽章提供指定區域。 了解這些欄位類型及其行為方式對於實現有效的表單自動化至關重要。

AcroForms 的結構使其非常適合透過程式進行操作。 因為每個字段都有一個名稱和一個值,所以你可以遍歷文件中的所有字段,讀取它們的當前值,並使用簡單的程式碼設定新值。 這種可預測的結構使得本指南中介紹的自動化工作流程成為可能。


如何開啟PDF文件並列出所有表單欄位?

在透過程式填寫 PDF 表單之前,您需要了解其結構。 開啟文件並列舉其字段,即可顯示用於設定值的字段名稱、字段類型以及任何現有內容。 當使用第三方表單時,如果沒有關於內部欄位結構的文檔,這項發現步驟尤其有價值。

輸入 PDF 文件

在這個範例中,我們將使用一個名為application-form.pdf現有 PDF 表單。 這可以是任何包含互動式表單欄位的 PDF 文件:政府表格、您所在組織的申請模板,或您需要處理的第三方文件。 下面的程式碼載入此文件並遍歷其所有互動式表單欄位。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/list-form-fields.cs
using IronPdf;

// Load an existing PDF form document
PdfDocument pdfForm = PdfDocument.FromFile("application-form.pdf");

// Access the form object and iterate through all fields
foreach (var field in pdfForm.Form)
{
    // Access field properties: field.Name, field.Type, field.Value, field.ReadOnly
}
Imports IronPdf

' Load an existing PDF form document
Dim pdfForm As PdfDocument = PdfDocument.FromFile("application-form.pdf")

' Access the form object and iterate through all fields
For Each field In pdfForm.Form
    ' Access field properties: field.Name, field.Type, field.Value, field.ReadOnly
Next
$vbLabelText   $csharpLabel

PdfDocument.FromFile()方法將 PDF 載入到記憶體中,而Form集合提供了對文件中每個互動式欄位的存取。 每個欄位都公開了諸如Name (用於程式存取的唯一識別碼)、 Type (文字欄位、複選框、單選按鈕、下拉清單或簽名)、 Value (目前內容)和ReadOnly (欄位是否可以修改)之類的屬性。 對不熟悉的表單執行此枚舉,即可獲得編寫正確填充表單的程式碼所需的完整欄位清單。

對於包含多個欄位的表單,您可能需要按類型篩選或搜尋特定欄位名稱。 FindFormField 方法透過字段的確切名稱查找字段,如果找不到匹配項,則會拋出異常。 當您不確定某個欄位是否存在時,請使用 try-catch 區塊。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/find-form-field.cs
using IronPdf;

PdfDocument pdfForm = PdfDocument.FromFile("employee-onboarding.pdf");

// Find specific fields by name - use try-catch for fields that may not exist
try
{
    var firstNameField = pdfForm.Form.FindFormField("firstName");
    // Use firstNameField.Value to get or set the field value
}
catch (Exception)
{
    // Field not found in this document
}

// For fields you know exist, you can access them directly
var lastNameField = pdfForm.Form.FindFormField("lastName");
var departmentField = pdfForm.Form.FindFormField("department");
Imports IronPdf

Dim pdfForm As PdfDocument = PdfDocument.FromFile("employee-onboarding.pdf")

' Find specific fields by name - use try-catch for fields that may not exist
Try
    Dim firstNameField = pdfForm.Form.FindFormField("firstName")
    ' Use firstNameField.Value to get or set the field value
Catch ex As Exception
    ' Field not found in this document
End Try

' For fields you know exist, you can access them directly
Dim lastNameField = pdfForm.Form.FindFormField("lastName")
Dim departmentField = pdfForm.Form.FindFormField("department")
$vbLabelText   $csharpLabel

有關讀取表單欄位值的更多詳細信息,請參閱C# 中的"提取 PDF 表單欄位"指南。


如何填入文字欄位、複選框和下拉清單?

一旦您知道 PDF 表單中的欄位名稱,填充它們只需要幾行程式碼。 每種欄位類型都接受特定格式的值。 文字欄位直接接受字串值。 複選框使用"是"表示選取狀態,並使用"否"表示未選取狀態。 單選按鈕接受所選選項的值。 下拉式選單欄位接受預定義選項清單中的任何值。

輸入 PDF 文件

我們將使用客戶註冊表單( customer-registration.pdf ),其中包含幾種欄位類型:姓名、電子郵件、電話和地址的文字欄位; 訂閱新聞簡報的複選框; 以及用於選擇帳戶類型的下拉式選單。 此範例載入表單並使用範例客戶資料填入每個欄位。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/fill-text-checkbox-dropdown.cs
using IronPdf;

// Load the form document
PdfDocument pdf = PdfDocument.FromFile("customer-registration.pdf");

// Fill text fields with customer information
pdf.Form.FindFormField("fullName").Value = "Sarah Johnson";
pdf.Form.FindFormField("email").Value = "sarah.johnson@example.com";
pdf.Form.FindFormField("phone").Value = "(555) 123-4567";
pdf.Form.FindFormField("address").Value = "742 Evergreen Terrace\r\nSpringfield, IL 62701";

// Check a checkbox field
pdf.Form.FindFormField("newsletterOptIn").Value = "Yes";

// Select an option from a dropdown
pdf.Form.FindFormField("accountType").Value = "Premium";

// Save the filled form
pdf.SaveAs("customer-registration-completed.pdf");
Imports IronPdf

' Load the form document
Dim pdf As PdfDocument = PdfDocument.FromFile("customer-registration.pdf")

' Fill text fields with customer information
pdf.Form.FindFormField("fullName").Value = "Sarah Johnson"
pdf.Form.FindFormField("email").Value = "sarah.johnson@example.com"
pdf.Form.FindFormField("phone").Value = "(555) 123-4567"
pdf.Form.FindFormField("address").Value = "742 Evergreen Terrace" & vbCrLf & "Springfield, IL 62701"

' Check a checkbox field
pdf.Form.FindFormField("newsletterOptIn").Value = "Yes"

' Select an option from a dropdown
pdf.Form.FindFormField("accountType").Value = "Premium"

' Save the filled form
pdf.SaveAs("customer-registration-completed.pdf")
$vbLabelText   $csharpLabel

範例輸出

FindFormField()方法透過字段的確切名稱定位每個字段,設定Value屬性即可填入字段內容。 請注意地址欄位中使用\r\n表示換行符號。 多行文字區域可以正確解釋這些轉義序列,使您可以格式化跨越多行的位址、註解和其他內容。 對於複選框,"是"和"否"值用於切換選取狀態,而下拉清單接受與其預先定義選項之一相符的任何值。

使用單選按鈕需要理解,同一組按鈕中的所有按鈕都共用同一個欄位名稱。 設定該值將選取符合的選項,並取消選取該群組中的所有其他選項。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/radio-button-group.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("survey-form.pdf");

// Get a radio button group and examine its options
var satisfactionField = pdf.Form.FindFormField("satisfactionLevel");

// Access available options from the radio button annotations
foreach (var annotation in satisfactionField.Annotations)
{
    // annotation.OnAppearance contains the option value
}

// Select one option from the group
satisfactionField.Value = "Very Satisfied";

pdf.SaveAs("survey-completed.pdf");
Imports IronPdf

Dim pdf As PdfDocument = PdfDocument.FromFile("survey-form.pdf")

' Get a radio button group and examine its options
Dim satisfactionField = pdf.Form.FindFormField("satisfactionLevel")

' Access available options from the radio button annotations
For Each annotation In satisfactionField.Annotations
    ' annotation.OnAppearance contains the option value
Next

' Select one option from the group
satisfactionField.Value = "Very Satisfied"

pdf.SaveAs("survey-completed.pdf")
$vbLabelText   $csharpLabel

下拉式選單的工作原理類似。 在設定值之前,您可以透過 Choices 屬性檢查可用的選項,以確保您的程式碼只嘗試選擇有效選項。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/dropdown-choices.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("order-form.pdf");

var shippingMethod = pdf.Form.FindFormField("shippingMethod");

// Access all available shipping options via shippingMethod.Choices

// Select express shipping
shippingMethod.Value = "Express (2-3 days)";

pdf.SaveAs("order-form-filled.pdf");
Imports IronPdf

Dim pdf As PdfDocument = PdfDocument.FromFile("order-form.pdf")

Dim shippingMethod = pdf.Form.FindFormField("shippingMethod")

' Access all available shipping options via shippingMethod.Choices

' Select express shipping
shippingMethod.Value = "Express (2-3 days)"

pdf.SaveAs("order-form-filled.pdf")
$vbLabelText   $csharpLabel

有關填寫所有表單欄位類型的全面指南,請參閱《C# 中的填寫和編輯 PDF 表單》《以程式設計方式填寫 PDF 表單》


如何根據資料物件和字典填入表單?

實際應用中很少會直接將表單值硬編碼到程式碼中。 相反,資料來自資料庫、API 回應、使用者輸入或設定檔。 將這些資料組織成字典或自訂對象,可以讓你的表單填寫程式碼更易於維護和重複使用。

輸入 PDF 文件

假設有一個貸款申請表( loan-application.pdf ),其中包含申請人資訊欄位:姓名、出生日期、社會安全號碼、地址欄位、就業狀況、年收入以及條款協議複選框。 以下程式碼使用儲存在Dictionary<string, string>中的資料填充表單。 Dictionary<string, string>其中每個字典鍵都與表單欄位名稱相符。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/fill-from-dictionary.cs
using IronPdf;
using System.Collections.Generic;

// Form data stored in a dictionary
var formData = new Dictionary<string, string>
{
    { "applicantName", "Michael Chen" },
    { "dateOfBirth", "1985-03-15" },
    { "ssn", "XXX-XX-1234" },
    { "streetAddress", "456 Oak Avenue" },
    { "city", "Portland" },
    { "state", "OR" },
    { "zipCode", "97201" },
    { "employmentStatus", "Full-Time" },
    { "annualIncome", "75000" },
    { "agreeToTerms", "Yes" }
};

PdfDocument pdf = PdfDocument.FromFile("loan-application.pdf");

// Iterate through the dictionary and fill matching fields
foreach (var entry in formData)
{
    var field = pdf.Form.FindFormField(entry.Key);
    if (field != null)
    {
        field.Value = entry.Value;
    }
}

pdf.SaveAs("loan-application-filled.pdf");
Imports IronPdf
Imports System.Collections.Generic

' Form data stored in a dictionary
Dim formData As New Dictionary(Of String, String) From {
    {"applicantName", "Michael Chen"},
    {"dateOfBirth", "1985-03-15"},
    {"ssn", "XXX-XX-1234"},
    {"streetAddress", "456 Oak Avenue"},
    {"city", "Portland"},
    {"state", "OR"},
    {"zipCode", "97201"},
    {"employmentStatus", "Full-Time"},
    {"annualIncome", "75000"},
    {"agreeToTerms", "Yes"}
}

Dim pdf As PdfDocument = PdfDocument.FromFile("loan-application.pdf")

' Iterate through the dictionary and fill matching fields
For Each entry In formData
    Dim field = pdf.Form.FindFormField(entry.Key)
    If field IsNot Nothing Then
        field.Value = entry.Value
    End If
Next

pdf.SaveAs("loan-application-filled.pdf")
$vbLabelText   $csharpLabel

範例輸出

基於字典的方法能夠清晰地將資料與邏輯分開。 foreach循環遍歷每個鍵值對,使用FindFormField()尋找對應的 PDF 字段,如果該字段存在,則賦值。 空值檢查( if (field != null) )可防止字典中包含與文件中任何欄位都不符的鍵時出現異常。 當處理可能包含表單中不存在的額外欄位的資料來源時,這尤其有用。

對於更複雜的場景,您可以定義一個表示表單資料的類,然後使用反射或映射函數將屬性值傳遞到表單欄位。

using IronPdf;
using System;

// Define a strongly-typed class for the form data
public class EmployeeRecord
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmployeeId { get; set; }
    public string Department { get; set; }
    public DateTime HireDate { get; set; }
    public string JobTitle { get; set; }
    public bool DirectDeposit { get; set; }
}

public class FormFiller
{
    public void FillEmployeeForm(EmployeeRecord employee, string templatePath, string outputPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(templatePath);

        // Map object properties to form fields
        pdf.Form.FindFormField("firstName").Value = employee.FirstName;
        pdf.Form.FindFormField("lastName").Value = employee.LastName;
        pdf.Form.FindFormField("employeeId").Value = employee.EmployeeId;
        pdf.Form.FindFormField("department").Value = employee.Department;
        pdf.Form.FindFormField("hireDate").Value = employee.HireDate.ToString("MM/dd/yyyy");
        pdf.Form.FindFormField("jobTitle").Value = employee.JobTitle;
        pdf.Form.FindFormField("directDeposit").Value = employee.DirectDeposit ? "Yes" : "No";

        pdf.SaveAs(outputPath);
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var employee = new EmployeeRecord
        {
            FirstName = "Jennifer",
            LastName = "Martinez",
            EmployeeId = "EMP-2024-0892",
            Department = "Engineering",
            HireDate = new DateTime(2024, 6, 15),
            JobTitle = "Senior Developer",
            DirectDeposit = true
        };

        var filler = new FormFiller();
        filler.FillEmployeeForm(employee, "new-hire-form.pdf", "jennifer-martinez-onboarding.pdf");
    }
}
using IronPdf;
using System;

// Define a strongly-typed class for the form data
public class EmployeeRecord
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmployeeId { get; set; }
    public string Department { get; set; }
    public DateTime HireDate { get; set; }
    public string JobTitle { get; set; }
    public bool DirectDeposit { get; set; }
}

public class FormFiller
{
    public void FillEmployeeForm(EmployeeRecord employee, string templatePath, string outputPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(templatePath);

        // Map object properties to form fields
        pdf.Form.FindFormField("firstName").Value = employee.FirstName;
        pdf.Form.FindFormField("lastName").Value = employee.LastName;
        pdf.Form.FindFormField("employeeId").Value = employee.EmployeeId;
        pdf.Form.FindFormField("department").Value = employee.Department;
        pdf.Form.FindFormField("hireDate").Value = employee.HireDate.ToString("MM/dd/yyyy");
        pdf.Form.FindFormField("jobTitle").Value = employee.JobTitle;
        pdf.Form.FindFormField("directDeposit").Value = employee.DirectDeposit ? "Yes" : "No";

        pdf.SaveAs(outputPath);
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var employee = new EmployeeRecord
        {
            FirstName = "Jennifer",
            LastName = "Martinez",
            EmployeeId = "EMP-2024-0892",
            Department = "Engineering",
            HireDate = new DateTime(2024, 6, 15),
            JobTitle = "Senior Developer",
            DirectDeposit = true
        };

        var filler = new FormFiller();
        filler.FillEmployeeForm(employee, "new-hire-form.pdf", "jennifer-martinez-onboarding.pdf");
    }
}
Imports IronPdf
Imports System

' Define a strongly-typed class for the form data
Public Class EmployeeRecord
    Public Property FirstName As String
    Public Property LastName As String
    Public Property EmployeeId As String
    Public Property Department As String
    Public Property HireDate As DateTime
    Public Property JobTitle As String
    Public Property DirectDeposit As Boolean
End Class

Public Class FormFiller
    Public Sub FillEmployeeForm(employee As EmployeeRecord, templatePath As String, outputPath As String)
        Dim pdf As PdfDocument = PdfDocument.FromFile(templatePath)

        ' Map object properties to form fields
        pdf.Form.FindFormField("firstName").Value = employee.FirstName
        pdf.Form.FindFormField("lastName").Value = employee.LastName
        pdf.Form.FindFormField("employeeId").Value = employee.EmployeeId
        pdf.Form.FindFormField("department").Value = employee.Department
        pdf.Form.FindFormField("hireDate").Value = employee.HireDate.ToString("MM/dd/yyyy")
        pdf.Form.FindFormField("jobTitle").Value = employee.JobTitle
        pdf.Form.FindFormField("directDeposit").Value = If(employee.DirectDeposit, "Yes", "No")

        pdf.SaveAs(outputPath)
    End Sub
End Class

' Usage example
Module Program
    Sub Main()
        Dim employee As New EmployeeRecord With {
            .FirstName = "Jennifer",
            .LastName = "Martinez",
            .EmployeeId = "EMP-2024-0892",
            .Department = "Engineering",
            .HireDate = New DateTime(2024, 6, 15),
            .JobTitle = "Senior Developer",
            .DirectDeposit = True
        }

        Dim filler As New FormFiller()
        filler.FillEmployeeForm(employee, "new-hire-form.pdf", "jennifer-martinez-onboarding.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

範例輸出


如何在填寫表單前驗證表單資料?

在填寫 PDF 表單之前,驗證資料有助於及早發現錯誤,並確保產生的文件符合要求。 雖然 PDF 表單可以包含自己的驗證規則,但僅依靠這些規則意味著錯誤只會在處理結束時才會顯現出來。 在 C# 程式碼中實現驗證可以讓你擁有更多控制權和更好的錯誤訊息。

using IronPdf;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class FormValidationResult
{
    public bool IsValid { get; set; }
    public List<string> Errors { get; set; } = new List<string>();
}

public class FormValidator
{
    public FormValidationResult ValidateApplicationData(Dictionary<string, string> formData, PdfDocument pdf)
    {
        var result = new FormValidationResult { IsValid = true };

        // Check that all required fields have values
        var requiredFields = new[] { "applicantName", "email", "phone", "ssn" };
        foreach (var fieldName in requiredFields)
        {
            if (!formData.ContainsKey(fieldName) || string.IsNullOrWhiteSpace(formData[fieldName]))
            {
                result.Errors.Add($"Required field '{fieldName}' is missing or empty");
                result.IsValid = false;
            }
        }

        // Validate email format
        if (formData.ContainsKey("email"))
        {
            var emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";
            if (!Regex.IsMatch(formData["email"], emailPattern))
            {
                result.Errors.Add("Email address format is invalid");
                result.IsValid = false;
            }
        }

        // Validate phone number format
        if (formData.ContainsKey("phone"))
        {
            var phonePattern = @"^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$";
            if (!Regex.IsMatch(formData["phone"], phonePattern))
            {
                result.Errors.Add("Phone number format is invalid");
                result.IsValid = false;
            }
        }

        // Verify that form fields exist in the PDF
        foreach (var fieldName in formData.Keys)
        {
            try
            {
                var field = pdf.Form.FindFormField(fieldName);
                // Field exists
            }
            catch
            {
                result.Errors.Add($"Field '{fieldName}' does not exist in the PDF form");
                result.IsValid = false;
            }
        }

        // Check dropdown values against available choices
        if (formData.ContainsKey("state"))
        {
            try
            {
                var stateField = pdf.Form.FindFormField("state");
                if (stateField.Choices != null)
                {
                    bool validChoice = false;
                    foreach (var choice in stateField.Choices)
                    {
                        if (choice == formData["state"])
                        {
                            validChoice = true;
                            break;
                        }
                    }
                    if (!validChoice)
                    {
                        result.Errors.Add($"'{formData["state"]}' is not a valid option for the state field");
                        result.IsValid = false;
                    }
                }
            }
            catch
            {
                // State field doesn't exist, skip validation
            }
        }

        return result;
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var formData = new Dictionary<string, string>
        {
            { "applicantName", "John Doe" },
            { "email", "invalid-email" },
            { "phone", "555-1234" },
            { "state", "XX" }
        };

        PdfDocument pdf = PdfDocument.FromFile("application.pdf");
        var validator = new FormValidator();
        var validationResult = validator.ValidateApplicationData(formData, pdf);

        if (validationResult.IsValid)
        {
            // Proceed with form fill
        }
        else
        {
            // Handle validation errors in validationResult.Errors
        }
    }
}
using IronPdf;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class FormValidationResult
{
    public bool IsValid { get; set; }
    public List<string> Errors { get; set; } = new List<string>();
}

public class FormValidator
{
    public FormValidationResult ValidateApplicationData(Dictionary<string, string> formData, PdfDocument pdf)
    {
        var result = new FormValidationResult { IsValid = true };

        // Check that all required fields have values
        var requiredFields = new[] { "applicantName", "email", "phone", "ssn" };
        foreach (var fieldName in requiredFields)
        {
            if (!formData.ContainsKey(fieldName) || string.IsNullOrWhiteSpace(formData[fieldName]))
            {
                result.Errors.Add($"Required field '{fieldName}' is missing or empty");
                result.IsValid = false;
            }
        }

        // Validate email format
        if (formData.ContainsKey("email"))
        {
            var emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";
            if (!Regex.IsMatch(formData["email"], emailPattern))
            {
                result.Errors.Add("Email address format is invalid");
                result.IsValid = false;
            }
        }

        // Validate phone number format
        if (formData.ContainsKey("phone"))
        {
            var phonePattern = @"^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$";
            if (!Regex.IsMatch(formData["phone"], phonePattern))
            {
                result.Errors.Add("Phone number format is invalid");
                result.IsValid = false;
            }
        }

        // Verify that form fields exist in the PDF
        foreach (var fieldName in formData.Keys)
        {
            try
            {
                var field = pdf.Form.FindFormField(fieldName);
                // Field exists
            }
            catch
            {
                result.Errors.Add($"Field '{fieldName}' does not exist in the PDF form");
                result.IsValid = false;
            }
        }

        // Check dropdown values against available choices
        if (formData.ContainsKey("state"))
        {
            try
            {
                var stateField = pdf.Form.FindFormField("state");
                if (stateField.Choices != null)
                {
                    bool validChoice = false;
                    foreach (var choice in stateField.Choices)
                    {
                        if (choice == formData["state"])
                        {
                            validChoice = true;
                            break;
                        }
                    }
                    if (!validChoice)
                    {
                        result.Errors.Add($"'{formData["state"]}' is not a valid option for the state field");
                        result.IsValid = false;
                    }
                }
            }
            catch
            {
                // State field doesn't exist, skip validation
            }
        }

        return result;
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var formData = new Dictionary<string, string>
        {
            { "applicantName", "John Doe" },
            { "email", "invalid-email" },
            { "phone", "555-1234" },
            { "state", "XX" }
        };

        PdfDocument pdf = PdfDocument.FromFile("application.pdf");
        var validator = new FormValidator();
        var validationResult = validator.ValidateApplicationData(formData, pdf);

        if (validationResult.IsValid)
        {
            // Proceed with form fill
        }
        else
        {
            // Handle validation errors in validationResult.Errors
        }
    }
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Public Class FormValidationResult
    Public Property IsValid As Boolean
    Public Property Errors As List(Of String) = New List(Of String)()
End Class

Public Class FormValidator
    Public Function ValidateApplicationData(formData As Dictionary(Of String, String), pdf As PdfDocument) As FormValidationResult
        Dim result As New FormValidationResult With {.IsValid = True}

        ' Check that all required fields have values
        Dim requiredFields = New String() {"applicantName", "email", "phone", "ssn"}
        For Each fieldName In requiredFields
            If Not formData.ContainsKey(fieldName) OrElse String.IsNullOrWhiteSpace(formData(fieldName)) Then
                result.Errors.Add($"Required field '{fieldName}' is missing or empty")
                result.IsValid = False
            End If
        Next

        ' Validate email format
        If formData.ContainsKey("email") Then
            Dim emailPattern = "^[^@\s]+@[^@\s]+\.[^@\s]+$"
            If Not Regex.IsMatch(formData("email"), emailPattern) Then
                result.Errors.Add("Email address format is invalid")
                result.IsValid = False
            End If
        End If

        ' Validate phone number format
        If formData.ContainsKey("phone") Then
            Dim phonePattern = "^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$"
            If Not Regex.IsMatch(formData("phone"), phonePattern) Then
                result.Errors.Add("Phone number format is invalid")
                result.IsValid = False
            End If
        End If

        ' Verify that form fields exist in the PDF
        For Each fieldName In formData.Keys
            Try
                Dim field = pdf.Form.FindFormField(fieldName)
                ' Field exists
            Catch
                result.Errors.Add($"Field '{fieldName}' does not exist in the PDF form")
                result.IsValid = False
            End Try
        Next

        ' Check dropdown values against available choices
        If formData.ContainsKey("state") Then
            Try
                Dim stateField = pdf.Form.FindFormField("state")
                If stateField.Choices IsNot Nothing Then
                    Dim validChoice = False
                    For Each choice In stateField.Choices
                        If choice = formData("state") Then
                            validChoice = True
                            Exit For
                        End If
                    Next
                    If Not validChoice Then
                        result.Errors.Add($"'{formData("state")}' is not a valid option for the state field")
                        result.IsValid = False
                    End If
                End If
            Catch
                ' State field doesn't exist, skip validation
            End Try
        End If

        Return result
    End Function
End Class

' Usage example
Class Program
    Shared Sub Main()
        Dim formData = New Dictionary(Of String, String) From {
            {"applicantName", "John Doe"},
            {"email", "invalid-email"},
            {"phone", "555-1234"},
            {"state", "XX"}
        }

        Dim pdf As PdfDocument = PdfDocument.FromFile("application.pdf")
        Dim validator As New FormValidator()
        Dim validationResult = validator.ValidateApplicationData(formData, pdf)

        If validationResult.IsValid Then
            ' Proceed with form fill
        Else
            ' Handle validation errors in validationResult.Errors
        End If
    End Sub
End Class
$vbLabelText   $csharpLabel

此驗證層檢查是否缺少必填字段,驗證常見資料類型的格式模式,確認表單選項中是否存在指定的下拉清單值,並驗證資料中的所有欄位名稱是否實際存在於 PDF 中。 在嘗試填寫表單之前發現這些問題,可以防止部分填寫,並使偵錯變得更加容易。


如何在PDF表單中建立文字輸入欄位?

從零開始建立 PDF 表單,您可以完全控製表單的結構和外觀。 IronPDF 的 HTML 轉 PDF 渲染引擎可以解析標準的 HTML 表單元素,並將其轉換為 PDF AcroForm 欄位。 這種方法可讓您使用熟悉的 Web 技術(包括用於樣式設定的 CSS)來設計表單。 有關建立表單的完整指南,請參閱C# 中的"建立 PDF 表單"

以下程式碼建立了一個包含文字輸入欄位和文字區域的客戶回饋表單,使用 HTML 和 CSS 定義表單結構和樣式。 輸出的PDF檔案包含可填寫表單字段,使用者可以在任何PDF閱讀器中填寫。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/create-text-input-form.cs
using IronPdf;

// Define the form layout using HTML with form elements
string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 20px;
        }
        h1 {
            color: #333;
            border-bottom: 2px solid #4CAF50;
            padding-bottom: 10px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        input[type='text'], textarea {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        textarea {
            height: 100px;
            resize: none;
        }
        .required::after {
            content: ' *';
            color: red;
        }
    </style>
</head>
<body>
    <h1>Customer Feedback Form</h1>
    <form>
        <div class='form-group'>
            <label class='required'>Full Name</label>
            <input type='text' name='customerName' />
        </div>
        <div class='form-group'>
            <label class='required'>Email Address</label>
            <input type='text' name='customerEmail' />
        </div>
        <div class='form-group'>
            <label>Phone Number</label>
            <input type='text' name='customerPhone' />
        </div>
        <div class='form-group'>
            <label>Order Number</label>
            <input type='text' name='orderNumber' />
        </div>
        <div class='form-group'>
            <label class='required'>Your Feedback</label>
            <textarea name='feedbackText'></textarea>
        </div>
    </form>
</body>
</html>";

// Create the renderer and enable form creation
ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

// Render the HTML to a PDF with interactive form fields
PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);
pdf.SaveAs("customer-feedback-form.pdf");
Imports IronPdf

' Define the form layout using HTML with form elements
Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 20px;
        }
        h1 {
            color: #333;
            border-bottom: 2px solid #4CAF50;
            padding-bottom: 10px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        input[type='text'], textarea {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        textarea {
            height: 100px;
            resize: none;
        }
        .required::after {
            content: ' *';
            color: red;
        }
    </style>
</head>
<body>
    <h1>Customer Feedback Form</h1>
    <form>
        <div class='form-group'>
            <label class='required'>Full Name</label>
            <input type='text' name='customerName' />
        </div>
        <div class='form-group'>
            <label class='required'>Email Address</label>
            <input type='text' name='customerEmail' />
        </div>
        <div class='form-group'>
            <label>Phone Number</label>
            <input type='text' name='customerPhone' />
        </div>
        <div class='form-group'>
            <label>Order Number</label>
            <input type='text' name='orderNumber' />
        </div>
        <div class='form-group'>
            <label class='required'>Your Feedback</label>
            <textarea name='feedbackText'></textarea>
        </div>
    </form>
</body>
</html>"

' Create the renderer and enable form creation
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

' Render the HTML to a PDF with interactive form fields
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)
pdf.SaveAs("customer-feedback-form.pdf")
$vbLabelText   $csharpLabel

範例輸出

關鍵設定是RenderingOptions中的CreatePdfFormsFromHtml = true ,它指示ChromePdfRenderer將 HTML 轉換為 PdfFormsFromHtml。<input><textarea>&lt;/code&gt; elements into their PDF AcroForm equivalents.</textarea> 如果沒有此設置,輸入內容將呈現為沒有互動性的靜態視覺元素。 每個輸入元素的name屬性將成為產生的 PDF 中的欄位名稱。 這些是您在以程式設計方式填寫表單時將使用的識別碼。 選擇描述性強、前後一致的名稱,讓表單填寫程式碼更易讀、更易於維護。 有關 HTML 到 PDF 轉換的更多信息,請參閱C# 中的 HTML 到 PDF 轉換教程。


如何在PDF表單中新增複選框和單選按鈕?

複選框和單選按鈕用於接收基於選擇的輸入。 在 HTML 中,複選框使用type=&#39;checkbox&#39; ,而單選按鈕使用type=&#39;radio&#39; 。 名稱屬性相同的單選按鈕會自動組成一個互斥組。

這段程式碼建立了一個活動註冊表單,其中包含多個用於選擇飲食偏好的複選框和用於選擇門票類型的單選按鈕。 HTML結構定義了表單佈局,而CSS提供了樣式。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/create-checkbox-radio-form.cs
using IronPdf;

string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 20px;
        }
        h1 {
            color: #2c3e50;
        }
        h2 {
            color: #34495e;
            font-size: 16px;
            margin-top: 25px;
        }
        .option-group {
            margin: 10px 0;
        }
        .option-group label {
            margin-left: 8px;
            cursor: pointer;
        }
        .checkbox-section {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
    </style>
</head>
<body>
    <h1>Event Registration</h1>
    <form>
        <h2>Select Your Ticket Type</h2>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='General' id='general' />
            <label for='general'>General Admission ($50)</label>
        </div>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='VIP' id='vip' />
            <label for='vip'>VIP Access ($150)</label>
        </div>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='Premium' id='premium' />
            <label for='premium'>Premium Package ($300)</label>
        </div>

        <h2>Which Sessions Will You Attend?</h2>
        <div class='checkbox-section'>
            <div class='option-group'>
                <input type='checkbox' name='sessionMorning' value='Yes' id='morning' />
                <label for='morning'>Morning Keynote (9:00 AM)</label>
            </div>
            <div class='option-group'>
                <input type='checkbox' name='sessionWorkshop' value='Yes' id='workshop' />
                <label for='workshop'>Afternoon Workshop (2:00 PM)</label>
            </div>
            <div class='option-group'>
                <input type='checkbox' name='sessionNetworking' value='Yes' id='networking' />
                <label for='networking'>Evening Networking (6:00 PM)</label>
            </div>
        </div>

        <h2>Dietary Requirements</h2>
        <div class='option-group'>
            <input type='checkbox' name='dietVegetarian' value='Yes' id='vegetarian' />
            <label for='vegetarian'>Vegetarian</label>
        </div>
        <div class='option-group'>
            <input type='checkbox' name='dietVegan' value='Yes' id='vegan' />
            <label for='vegan'>Vegan</label>
        </div>
        <div class='option-group'>
            <input type='checkbox' name='dietGlutenFree' value='Yes' id='glutenfree' />
            <label for='glutenfree'>Gluten-Free</label>
        </div>
    </form>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);
pdf.SaveAs("event-registration-form.pdf");
Imports IronPdf

Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 20px;
        }
        h1 {
            color: #2c3e50;
        }
        h2 {
            color: #34495e;
            font-size: 16px;
            margin-top: 25px;
        }
        .option-group {
            margin: 10px 0;
        }
        .option-group label {
            margin-left: 8px;
            cursor: pointer;
        }
        .checkbox-section {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
    </style>
</head>
<body>
    <h1>Event Registration</h1>
    <form>
        <h2>Select Your Ticket Type</h2>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='General' id='general' />
            <label for='general'>General Admission ($50)</label>
        </div>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='VIP' id='vip' />
            <label for='vip'>VIP Access ($150)</label>
        </div>
        <div class='option-group'>
            <input type='radio' name='ticketType' value='Premium' id='premium' />
            <label for='premium'>Premium Package ($300)</label>
        </div>

        <h2>Which Sessions Will You Attend?</h2>
        <div class='checkbox-section'>
            <div class='option-group'>
                <input type='checkbox' name='sessionMorning' value='Yes' id='morning' />
                <label for='morning'>Morning Keynote (9:00 AM)</label>
            </div>
            <div class='option-group'>
                <input type='checkbox' name='sessionWorkshop' value='Yes' id='workshop' />
                <label for='workshop'>Afternoon Workshop (2:00 PM)</label>
            </div>
            <div class='option-group'>
                <input type='checkbox' name='sessionNetworking' value='Yes' id='networking' />
                <label for='networking'>Evening Networking (6:00 PM)</label>
            </div>
        </div>

        <h2>Dietary Requirements</h2>
        <div class='option-group'>
            <input type='checkbox' name='dietVegetarian' value='Yes' id='vegetarian' />
            <label for='vegetarian'>Vegetarian</label>
        </div>
        <div class='option-group'>
            <input type='checkbox' name='dietVegan' value='Yes' id='vegan' />
            <label for='vegan'>Vegan</label>
        </div>
        <div class='option-group'>
            <input type='checkbox' name='dietGlutenFree' value='Yes' id='glutenfree' />
            <label for='glutenfree'>Gluten-Free</label>
        </div>
    </form>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)
pdf.SaveAs("event-registration-form.pdf")
$vbLabelText   $csharpLabel

範例輸出

請注意,這三個單選按鈕的name=&#39;ticketType&#39; ,它們組成一個群組,每個群組只能選擇一個選項。 每個複選框都有一個唯一的名稱,因為它們代表可以任意組合選擇的獨立選項。


如何在PDF表單中建立下拉清單?

下拉清單既節省空間,又能提供多個預定義選項。 HTML<select>元素<option>children 建立一個 PDF 組合框欄位。 使用者點擊該欄位即可顯示選項清單並選擇其中一個。

在這裡,我們建立了一個工作申請表,其中包含多個下拉式選單,用於選擇部門、經驗等級、首選開始日期和工作地點。 每個<select>元素包含預定義的<option>價值觀。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/create-dropdown-form.cs
using IronPdf;

string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            max-width: 650px;
            margin: 30px auto;
            padding: 25px;
            background: #fff;
        }
        h1 {
            color: #1a5f7a;
            margin-bottom: 30px;
        }
        .form-row {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }
        .form-group {
            flex: 1;
        }
        label {
            display: block;
            margin-bottom: 6px;
            font-weight: 600;
            color: #333;
        }
        select, input[type='text'] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 14px;
            box-sizing: border-box;
        }
    </style>
</head>
<body>
    <h1>Job Application Form</h1>
    <form>
        <div class='form-row'>
            <div class='form-group'>
                <label>First Name</label>
                <input type='text' name='firstName' />
            </div>
            <div class='form-group'>
                <label>Last Name</label>
                <input type='text' name='lastName' />
            </div>
        </div>

        <div class='form-row'>
            <div class='form-group'>
                <label>Department</label>
                <select name='department'>
                    <option value=''>Select Department</option>
                    <option value='Engineering'>Engineering</option>
                    <option value='Marketing'>Marketing</option>
                    <option value='Sales'>Sales</option>
                    <option value='Human Resources'>Human Resources</option>
                    <option value='Finance'>Finance</option>
                    <option value='Operations'>Operations</option>
                </select>
            </div>
            <div class='form-group'>
                <label>Experience Level</label>
                <select name='experienceLevel'>
                    <option value=''>Select Level</option>
                    <option value='Entry'>Entry Level (0-2 years)</option>
                    <option value='Mid'>Mid Level (3-5 years)</option>
                    <option value='Senior'>Senior (6-10 years)</option>
                    <option value='Executive'>Executive (10+ years)</option>
                </select>
            </div>
        </div>

        <div class='form-row'>
            <div class='form-group'>
                <label>Preferred Start Date</label>
                <select name='startDate'>
                    <option value='Immediate'>Immediately</option>
                    <option value='TwoWeeks'>In 2 weeks</option>
                    <option value='OneMonth'>In 1 month</option>
                    <option value='Flexible'>Flexible</option>
                </select>
            </div>
            <div class='form-group'>
                <label>Work Location Preference</label>
                <select name='workLocation'>
                    <option value='OnSite'>On-Site</option>
                    <option value='Remote'>Fully Remote</option>
                    <option value='Hybrid'>Hybrid</option>
                </select>
            </div>
        </div>
    </form>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);
pdf.SaveAs("job-application-form.pdf");
Imports IronPdf

Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            max-width: 650px;
            margin: 30px auto;
            padding: 25px;
            background: #fff;
        }
        h1 {
            color: #1a5f7a;
            margin-bottom: 30px;
        }
        .form-row {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }
        .form-group {
            flex: 1;
        }
        label {
            display: block;
            margin-bottom: 6px;
            font-weight: 600;
            color: #333;
        }
        select, input[type='text'] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 14px;
            box-sizing: border-box;
        }
    </style>
</head>
<body>
    <h1>Job Application Form</h1>
    <form>
        <div class='form-row'>
            <div class='form-group'>
                <label>First Name</label>
                <input type='text' name='firstName' />
            </div>
            <div class='form-group'>
                <label>Last Name</label>
                <input type='text' name='lastName' />
            </div>
        </div>

        <div class='form-row'>
            <div class='form-group'>
                <label>Department</label>
                <select name='department'>
                    <option value=''>Select Department</option>
                    <option value='Engineering'>Engineering</option>
                    <option value='Marketing'>Marketing</option>
                    <option value='Sales'>Sales</option>
                    <option value='Human Resources'>Human Resources</option>
                    <option value='Finance'>Finance</option>
                    <option value='Operations'>Operations</option>
                </select>
            </div>
            <div class='form-group'>
                <label>Experience Level</label>
                <select name='experienceLevel'>
                    <option value=''>Select Level</option>
                    <option value='Entry'>Entry Level (0-2 years)</option>
                    <option value='Mid'>Mid Level (3-5 years)</option>
                    <option value='Senior'>Senior (6-10 years)</option>
                    <option value='Executive'>Executive (10+ years)</option>
                </select>
            </div>
        </div>

        <div class='form-row'>
            <div class='form-group'>
                <label>Preferred Start Date</label>
                <select name='startDate'>
                    <option value='Immediate'>Immediately</option>
                    <option value='TwoWeeks'>In 2 weeks</option>
                    <option value='OneMonth'>In 1 month</option>
                    <option value='Flexible'>Flexible</option>
                </select>
            </div>
            <div class='form-group'>
                <label>Work Location Preference</label>
                <select name='workLocation'>
                    <option value='OnSite'>On-Site</option>
                    <option value='Remote'>Fully Remote</option>
                    <option value='Hybrid'>Hybrid</option>
                </select>
            </div>
        </div>
    </form>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)
pdf.SaveAs("job-application-form.pdf")
$vbLabelText   $csharpLabel

範例輸出

第一個<option>每個選擇元素(值為空)都用作佔位符提示,例如"選擇部門"。 當 PDF 渲染時,這些字段會變成組合框字段,使用者可以點擊這些字段來顯示完整的選項列表。 以程式設定填寫此表單時,請將欄位值設為與其中一個選項值完全匹配,例如"工程"或"遠端"。


如何在PDF表單中新增簽名域?

簽名欄是使用者可以套用數位簽章的區域。 雖然 HTML 沒有原生的簽名輸入類型,但 IronPDF 允許您以程式設計方式為任何 PDF 文件新增簽名欄位。

下面的程式碼首先從 HTML 建立一個保密協定文檔,然後以程式設計方式在頁面上的特定位置新增一個SignatureFormField 。 簽名域使用 PDF 座標(x、y、寬度、高度,單位為磅)進行定位。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/add-signature-field.cs
using IronPdf;
using IronSoftware.Forms;

// First create the base form using HTML
string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 30px;
        }
        h1 {
            text-align: center;
            color: #2c3e50;
        }
        .agreement-text {
            background: #f5f5f5;
            padding: 20px;
            border-radius: 5px;
            margin: 20px 0;
            line-height: 1.6;
        }
        .signature-section {
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
        }
        .signature-line {
            margin-top: 60px;
            border-bottom: 1px solid #333;
            width: 300px;
        }
        .signature-label {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        .date-field {
            margin-top: 20px;
        }
        .date-field label {
            font-weight: bold;
        }
        .date-field input {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 150px;
        }
    </style>
</head>
<body>
    <h1>Non-Disclosure Agreement</h1>

    <div class='agreement-text'>
        <p>By signing this document, I acknowledge that I have read and understood
        the terms of the Non-Disclosure Agreement dated as of the date signed below.
        I agree to maintain the confidentiality of all proprietary information
        disclosed to me during my engagement with the Company.</p>

        <p>I understand that violation of this agreement may result in legal action
        and that I am bound by these terms for a period of five (5) years from the
        date of signature.</p>
    </div>

    <div class='signature-section'>
        <div class='date-field'>
            <label>Date:</label>
            <input type='text' name='signatureDate' />
        </div>

        <div class='signature-line'></div>
        <div class='signature-label'>Authorized Signature</div>
    </div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);

// Add a signature field programmatically
// Parameters: name, page index, x position, y position, width, height
SignatureFormField signatureField = new SignatureFormField(
    "authorizedSignature",  // Field name
    0,                      // Page index (first page)
    72,                     // X position in points from left
    200,                    // Y position in points from bottom
    250,                    // Width in points
    60                      // Height in points
);

pdf.Form.Add(signatureField);
pdf.SaveAs("nda-with-signature.pdf");
Imports IronPdf
Imports IronSoftware.Forms

' First create the base form using HTML
Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 40px auto;
            padding: 30px;
        }
        h1 {
            text-align: center;
            color: #2c3e50;
        }
        .agreement-text {
            background: #f5f5f5;
            padding: 20px;
            border-radius: 5px;
            margin: 20px 0;
            line-height: 1.6;
        }
        .signature-section {
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
        }
        .signature-line {
            margin-top: 60px;
            border-bottom: 1px solid #333;
            width: 300px;
        }
        .signature-label {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        .date-field {
            margin-top: 20px;
        }
        .date-field label {
            font-weight: bold;
        }
        .date-field input {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 150px;
        }
    </style>
</head>
<body>
    <h1>Non-Disclosure Agreement</h1>

    <div class='agreement-text'>
        <p>By signing this document, I acknowledge that I have read and understood
        the terms of the Non-Disclosure Agreement dated as of the date signed below.
        I agree to maintain the confidentiality of all proprietary information
        disclosed to me during my engagement with the Company.</p>

        <p>I understand that violation of this agreement may result in legal action
        and that I am bound by these terms for a period of five (5) years from the
        date of signature.</p>
    </div>

    <div class='signature-section'>
        <div class='date-field'>
            <label>Date:</label>
            <input type='text' name='signatureDate' />
        </div>

        <div class='signature-line'></div>
        <div class='signature-label'>Authorized Signature</div>
    </div>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)

' Add a signature field programmatically
' Parameters: name, page index, x position, y position, width, height
Dim signatureField As New SignatureFormField(
    "authorizedSignature",  ' Field name
    0,                      ' Page index (first page)
    72,                     ' X position in points from left
    200,                    ' Y position in points from bottom
    250,                    ' Width in points
    60                      ' Height in points
)

pdf.Form.Add(signatureField)
pdf.SaveAs("nda-with-signature.pdf")
$vbLabelText   $csharpLabel

範例輸出

SignatureFormField建構函數接受六個參數:欄位名稱("authorizedSignature")、頁面索引(第一頁為 0)以及以磅為單位的位置/大小(x=72,y=200,寬度=250,高度=60)。 PDF 座標從頁面左下角開始,每英吋 72 點。 在支援數位簽章的 PDF 閱讀器中,簽章欄會顯示為一個互動式區域。 使用者可以點擊此欄位以應用基於憑證的簽名。

有關數位簽章(包括基於憑證的簽章)的更多信息,請參閱C# PDF 數位簽章指南C# PDF 數位簽章範例


如何設定表單元素的樣式和位置?

使用 CSS 從 HTML 建立 PDF 時,可以對表單外觀進行廣泛的控制。 您可以調整顏色、字體、邊框、間距和佈局,以符合您組織的品牌形像或滿足特定的設計要求。

這段程式碼片段使用高級 CSS 功能(包括 Google 字體、漸變背景、用於雙列佈局的 CSS Grid 以及帶有圓角和焦點狀態的自訂表單欄位樣式)創建了一個視覺效果精美的聯繫請求表單。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/styled-form-css.cs
using IronPdf;

string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');

        body {
            font-family: 'Inter', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            margin: 0;
            padding: 40px;
            box-sizing: border-box;
        }

        .form-container {
            background: white;
            max-width: 550px;
            margin: 0 auto;
            padding: 40px;
            border-radius: 12px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }

        h1 {
            margin: 0 0 10px 0;
            color: #1a1a2e;
            font-weight: 600;
        }

        .subtitle {
            color: #666;
            margin-bottom: 30px;
            font-size: 14px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
            font-size: 14px;
        }

        input[type='text'], select, textarea {
            width: 100%;
            padding: 12px 16px;
            border: 2px solid #e1e1e1;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s;
            box-sizing: border-box;
            font-family: 'Inter', sans-serif;
        }

        input[type='text']:focus, select:focus, textarea:focus {
            border-color: #667eea;
            outline: none;
        }

        textarea {
            height: 120px;
            resize: none;
        }

        .checkbox-group {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 12px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .checkbox-group input[type='checkbox'] {
            width: 20px;
            height: 20px;
            accent-color: #667eea;
        }

        .two-column {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
        }

        .footer-note {
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid #eee;
            font-size: 12px;
            color: #888;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class='form-container'>
        <h1>Contact Request</h1>
        <p class='subtitle'>Fill out the form below and we will get back to you within 24 hours.</p>

        <form>
            <div class='two-column'>
                <div class='form-group'>
                    <label>First Name</label>
                    <input type='text' name='firstName' />
                </div>
                <div class='form-group'>
                    <label>Last Name</label>
                    <input type='text' name='lastName' />
                </div>
            </div>

            <div class='form-group'>
                <label>Email Address</label>
                <input type='text' name='email' />
            </div>

            <div class='form-group'>
                <label>Subject</label>
                <select name='subject'>
                    <option value=''>Choose a topic...</option>
                    <option value='General'>General Inquiry</option>
                    <option value='Support'>Technical Support</option>
                    <option value='Sales'>Sales Question</option>
                    <option value='Partnership'>Partnership Opportunity</option>
                </select>
            </div>

            <div class='form-group'>
                <label>Message</label>
                <textarea name='message'></textarea>
            </div>

            <div class='form-group'>
                <div class='checkbox-group'>
                    <input type='checkbox' name='newsletter' value='Yes' id='newsletter' />
                    <label for='newsletter' style='margin: 0; font-weight: normal;'>
                        Subscribe to our newsletter for updates
                    </label>
                </div>
            </div>
        </form>

        <p class='footer-note'>Your information is secure and will never be shared with third parties.</p>
    </div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

// Set page size and margins
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 0;
renderer.RenderingOptions.MarginBottom = 0;
renderer.RenderingOptions.MarginLeft = 0;
renderer.RenderingOptions.MarginRight = 0;

PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);
pdf.SaveAs("styled-contact-form.pdf");
Imports IronPdf

Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');

        body {
            font-family: 'Inter', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            margin: 0;
            padding: 40px;
            box-sizing: border-box;
        }

        .form-container {
            background: white;
            max-width: 550px;
            margin: 0 auto;
            padding: 40px;
            border-radius: 12px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }

        h1 {
            margin: 0 0 10px 0;
            color: #1a1a2e;
            font-weight: 600;
        }

        .subtitle {
            color: #666;
            margin-bottom: 30px;
            font-size: 14px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
            font-size: 14px;
        }

        input[type='text'], select, textarea {
            width: 100%;
            padding: 12px 16px;
            border: 2px solid #e1e1e1;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s;
            box-sizing: border-box;
            font-family: 'Inter', sans-serif;
        }

        input[type='text']:focus, select:focus, textarea:focus {
            border-color: #667eea;
            outline: none;
        }

        textarea {
            height: 120px;
            resize: none;
        }

        .checkbox-group {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 12px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .checkbox-group input[type='checkbox'] {
            width: 20px;
            height: 20px;
            accent-color: #667eea;
        }

        .two-column {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
        }

        .footer-note {
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid #eee;
            font-size: 12px;
            color: #888;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class='form-container'>
        <h1>Contact Request</h1>
        <p class='subtitle'>Fill out the form below and we will get back to you within 24 hours.</p>

        <form>
            <div class='two-column'>
                <div class='form-group'>
                    <label>First Name</label>
                    <input type='text' name='firstName' />
                </div>
                <div class='form-group'>
                    <label>Last Name</label>
                    <input type='text' name='lastName' />
                </div>
            </div>

            <div class='form-group'>
                <label>Email Address</label>
                <input type='text' name='email' />
            </div>

            <div class='form-group'>
                <label>Subject</label>
                <select name='subject'>
                    <option value=''>Choose a topic...</option>
                    <option value='General'>General Inquiry</option>
                    <option value='Support'>Technical Support</option>
                    <option value='Sales'>Sales Question</option>
                    <option value='Partnership'>Partnership Opportunity</option>
                </select>
            </div>

            <div class='form-group'>
                <label>Message</label>
                <textarea name='message'></textarea>
            </div>

            <div class='form-group'>
                <div class='checkbox-group'>
                    <input type='checkbox' name='newsletter' value='Yes' id='newsletter' />
                    <label for='newsletter' style='margin: 0; font-weight: normal;'>
                        Subscribe to our newsletter for updates
                    </label>
                </div>
            </div>
        </form>

        <p class='footer-note'>Your information is secure and will never be shared with third parties.</p>
    </div>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

' Set page size and margins
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 0
renderer.RenderingOptions.MarginBottom = 0
renderer.RenderingOptions.MarginLeft = 0
renderer.RenderingOptions.MarginRight = 0

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)
pdf.SaveAs("styled-contact-form.pdf")
$vbLabelText   $csharpLabel

範例輸出

HTML 使用了 Google Fonts 中的 Inter 字體( @import url(...) ),為 body 應用了漸變背景,並為表單容器設定了圓角和陰影樣式。 RenderingOptions將所有邊距設為零,並使用 A4 紙張大小,以確保漸層填滿整個頁面。 儘管樣式複雜,但產生的 PDF 中所有表單欄位仍然完全可互動。 用戶可以點擊並在每個欄位中輸入內容。

有關 CSS 渲染選項和響應式佈局的更多信息,請參閱"使用響應式 CSS 將 HTML 轉換為 PDF""在 PDF 中使用渲染選項"


如何從已填寫的PDF表單中擷取資料?

使用者填寫 PDF 表單後,您的應用程式需要檢索輸入的值以進行處理、儲存或傳輸到其他系統。 提取表單資料的過程與填寫過程相反,是從欄位讀取值而不是向欄位中寫入值。

輸入 PDF 文件

假設您收到了一份使用者已經填寫完畢的申請表( completed-application.pdf )。 這是一個常見的場景,即您透過電子郵件、文件上傳或文件管理系統收到提交的表單,並且需要提取資料以進行資料庫儲存或進一步處理。 下面的程式碼載入已填寫的表單,並將所有欄位值提取到字典中。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/extract-form-data.cs
using IronPdf;
using System.Collections.Generic;

// Load a filled PDF form
PdfDocument filledForm = PdfDocument.FromFile("completed-application.pdf");

// Extract all form data into a dictionary
var extractedData = new Dictionary<string, string>();

foreach (var field in filledForm.Form)
{
    extractedData[field.Name] = field.Value ?? string.Empty;
}

// Access extracted data
// extractedData.GetValueOrDefault("firstName")
// extractedData.GetValueOrDefault("lastName")
// extractedData.GetValueOrDefault("email")
// extractedData.GetValueOrDefault("department")
Imports IronPdf
Imports System.Collections.Generic

' Load a filled PDF form
Dim filledForm As PdfDocument = PdfDocument.FromFile("completed-application.pdf")

' Extract all form data into a dictionary
Dim extractedData As New Dictionary(Of String, String)()

For Each field In filledForm.Form
    extractedData(field.Name) = If(field.Value, String.Empty)
Next

' Access extracted data
' extractedData.TryGetValue("firstName", Nothing)
' extractedData.TryGetValue("lastName", Nothing)
' extractedData.TryGetValue("email", Nothing)
' extractedData.TryGetValue("department", Nothing)
$vbLabelText   $csharpLabel

提取過程遍歷Form集合,讀取每個欄位的NameValue屬性。 空合併運算子(??string.Empty`) 確保空白欄位或未設定的欄位傳回空字串而不是 null,從而防止下游處理中出現空引用問題。 提取後,該字典可以透過欄位名稱作為鍵輕鬆存取任何欄位值。

為了進行更結構化的資料擷取,您可以將表單欄位直接對應到強型別物件。

using IronPdf;
using System;

public class ApplicationData
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Department { get; set; }
    public string ExperienceLevel { get; set; }
    public bool AcceptsTerms { get; set; }
}

public class FormDataExtractor
{
    public ApplicationData ExtractApplicationData(string pdfPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(pdfPath);

        return new ApplicationData
        {
            FirstName = GetFieldValue(pdf, "firstName"),
            LastName = GetFieldValue(pdf, "lastName"),
            Email = GetFieldValue(pdf, "email"),
            Phone = GetFieldValue(pdf, "phone"),
            Department = GetFieldValue(pdf, "department"),
            ExperienceLevel = GetFieldValue(pdf, "experienceLevel"),
            AcceptsTerms = GetFieldValue(pdf, "acceptTerms") == "Yes"
        };
    }

    private string GetFieldValue(PdfDocument pdf, string fieldName)
    {
        var field = pdf.Form.FindFormField(fieldName);
        return field?.Value ?? string.Empty;
    }
}

// Usage
class Program
{
    static void Main()
    {
        var extractor = new FormDataExtractor();
        var application = extractor.ExtractApplicationData("submitted-form.pdf");

        // Access application.FirstName, application.LastName, application.Department, etc.
    }
}
using IronPdf;
using System;

public class ApplicationData
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Department { get; set; }
    public string ExperienceLevel { get; set; }
    public bool AcceptsTerms { get; set; }
}

public class FormDataExtractor
{
    public ApplicationData ExtractApplicationData(string pdfPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(pdfPath);

        return new ApplicationData
        {
            FirstName = GetFieldValue(pdf, "firstName"),
            LastName = GetFieldValue(pdf, "lastName"),
            Email = GetFieldValue(pdf, "email"),
            Phone = GetFieldValue(pdf, "phone"),
            Department = GetFieldValue(pdf, "department"),
            ExperienceLevel = GetFieldValue(pdf, "experienceLevel"),
            AcceptsTerms = GetFieldValue(pdf, "acceptTerms") == "Yes"
        };
    }

    private string GetFieldValue(PdfDocument pdf, string fieldName)
    {
        var field = pdf.Form.FindFormField(fieldName);
        return field?.Value ?? string.Empty;
    }
}

// Usage
class Program
{
    static void Main()
    {
        var extractor = new FormDataExtractor();
        var application = extractor.ExtractApplicationData("submitted-form.pdf");

        // Access application.FirstName, application.LastName, application.Department, etc.
    }
}
Imports IronPdf
Imports System

Public Class ApplicationData
    Public Property FirstName As String
    Public Property LastName As String
    Public Property Email As String
    Public Property Phone As String
    Public Property Department As String
    Public Property ExperienceLevel As String
    Public Property AcceptsTerms As Boolean
End Class

Public Class FormDataExtractor
    Public Function ExtractApplicationData(pdfPath As String) As ApplicationData
        Dim pdf As PdfDocument = PdfDocument.FromFile(pdfPath)

        Return New ApplicationData With {
            .FirstName = GetFieldValue(pdf, "firstName"),
            .LastName = GetFieldValue(pdf, "lastName"),
            .Email = GetFieldValue(pdf, "email"),
            .Phone = GetFieldValue(pdf, "phone"),
            .Department = GetFieldValue(pdf, "department"),
            .ExperienceLevel = GetFieldValue(pdf, "experienceLevel"),
            .AcceptsTerms = GetFieldValue(pdf, "acceptTerms") = "Yes"
        }
    End Function

    Private Function GetFieldValue(pdf As PdfDocument, fieldName As String) As String
        Dim field = pdf.Form.FindFormField(fieldName)
        Return If(field?.Value, String.Empty)
    End Function
End Class

' Usage
Class Program
    Shared Sub Main()
        Dim extractor As New FormDataExtractor()
        Dim application = extractor.ExtractApplicationData("submitted-form.pdf")

        ' Access application.FirstName, application.LastName, application.Department, etc.
    End Sub
End Class
$vbLabelText   $csharpLabel

有關讀取表單資料的更多範例,請參閱C# PDF 表單範例提取 PDF 表單欄位指南


如何將PDF表單展平以鎖定欄位值?

將 PDF 表單扁平化會將互動式欄位轉換為靜態內容。 視覺效果不變,但使用者無法再編輯數值。 這項技術有多種用途:建立已完成表格的永久記錄、準備文件以供存檔以及防止提交後發生意外或故意的修改。

輸入 PDF 文件

這裡我們將使用一個合約範本( contract-template.pdf ),其中包含客戶名稱、合約日期、合約金額和付款條款等欄位。 這與典型的工作流程類似,即在模板中填寫具體的交易信息,然後鎖定字段以創建最終的、防篡改的文檔。 以下程式碼載入模板,填寫合約詳情,並將所有欄位設定為唯讀。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/flatten-form-readonly.cs
using IronPdf;

// Load and fill the form
PdfDocument pdf = PdfDocument.FromFile("contract-template.pdf");

pdf.Form.FindFormField("clientName").Value = "Acme Corporation";
pdf.Form.FindFormField("contractDate").Value = "January 15, 2025";
pdf.Form.FindFormField("contractValue").Value = "$50,000";
pdf.Form.FindFormField("paymentTerms").Value = "Net 30";

// Make all form fields read-only to prevent further editing
foreach (var field in pdf.Form)
{
    field.ReadOnly = true;
}

// Save the document with locked fields
pdf.SaveAs("contract-acme-signed.pdf");
Imports IronPdf

' Load and fill the form
Dim pdf As PdfDocument = PdfDocument.FromFile("contract-template.pdf")

pdf.Form.FindFormField("clientName").Value = "Acme Corporation"
pdf.Form.FindFormField("contractDate").Value = "January 15, 2025"
pdf.Form.FindFormField("contractValue").Value = "$50,000"
pdf.Form.FindFormField("paymentTerms").Value = "Net 30"

' Make all form fields read-only to prevent further editing
For Each field In pdf.Form
    field.ReadOnly = True
Next

' Save the document with locked fields
pdf.SaveAs("contract-acme-signed.pdf")
$vbLabelText   $csharpLabel

範例輸出

程式碼首先使用合約詳細資料填入clientNamecontractDatecontractValuepaymentTerms等欄位。 然後, foreach循環遍歷表單中的每個字段,並將field.ReadOnly = true ,這將鎖定每個字段,防止進一步編輯。 儲存後,使用者仍然可以在任何 PDF 閱讀器中查看表單值,但點擊欄位將無法進行修改。 這種技術可以建立適用於存檔或法律文件的永久記錄。

有關包括密碼保護在內的其他 PDF 安全選項,請參閱"簽名和保護 PDF 教學""PDF 密碼保護指南"


如何預先填寫供最終使用者使用的 PDF 表單?

預先填寫已知資訊的表格可以減少資料輸入,從而改善使用者體驗。 當您的系統中已有客戶資訊時,您可以在傳送文件之前填入表單字段,讓使用者僅查看和填寫剩餘欄位。

using IronPdf;
using System;

public class CustomerPortalService
{
    public byte[] GeneratePreFilledRenewalForm(int customerId)
    {
        // Simulate fetching customer data from database
        var customer = GetCustomerById(customerId);

        // Load the renewal form template
        PdfDocument pdf = PdfDocument.FromFile("templates/subscription-renewal.pdf");

        // Pre-fill known customer information
        pdf.Form.FindFormField("customerId").Value = customer.Id.ToString();
        pdf.Form.FindFormField("customerName").Value = customer.FullName;
        pdf.Form.FindFormField("email").Value = customer.Email;
        pdf.Form.FindFormField("phone").Value = customer.Phone;
        pdf.Form.FindFormField("address").Value = customer.Address;
        pdf.Form.FindFormField("currentPlan").Value = customer.SubscriptionPlan;
        pdf.Form.FindFormField("renewalDate").Value = DateTime.Now.AddDays(30).ToString("MM/dd/yyyy");

        // Leave editable fields empty for customer input:
        // - newPlan (dropdown for plan selection)
        // - paymentMethod (radio buttons)
        // - additionalNotes (textarea)
        // - signature (signature field)

        // Return as byte array for web download or email attachment
        return pdf.BinaryData;
    }

    // Simulated data access
    private Customer GetCustomerById(int id)
    {
        return new Customer
        {
            Id = id,
            FullName = "Robert Williams",
            Email = "robert.williams@email.com",
            Phone = "(555) 987-6543",
            Address = "123 Business Park Drive\r\nSuite 400\r\nChicago, IL 60601",
            SubscriptionPlan = "Professional"
        };
    }
}

public class Customer
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public string SubscriptionPlan { get; set; }
}
using IronPdf;
using System;

public class CustomerPortalService
{
    public byte[] GeneratePreFilledRenewalForm(int customerId)
    {
        // Simulate fetching customer data from database
        var customer = GetCustomerById(customerId);

        // Load the renewal form template
        PdfDocument pdf = PdfDocument.FromFile("templates/subscription-renewal.pdf");

        // Pre-fill known customer information
        pdf.Form.FindFormField("customerId").Value = customer.Id.ToString();
        pdf.Form.FindFormField("customerName").Value = customer.FullName;
        pdf.Form.FindFormField("email").Value = customer.Email;
        pdf.Form.FindFormField("phone").Value = customer.Phone;
        pdf.Form.FindFormField("address").Value = customer.Address;
        pdf.Form.FindFormField("currentPlan").Value = customer.SubscriptionPlan;
        pdf.Form.FindFormField("renewalDate").Value = DateTime.Now.AddDays(30).ToString("MM/dd/yyyy");

        // Leave editable fields empty for customer input:
        // - newPlan (dropdown for plan selection)
        // - paymentMethod (radio buttons)
        // - additionalNotes (textarea)
        // - signature (signature field)

        // Return as byte array for web download or email attachment
        return pdf.BinaryData;
    }

    // Simulated data access
    private Customer GetCustomerById(int id)
    {
        return new Customer
        {
            Id = id,
            FullName = "Robert Williams",
            Email = "robert.williams@email.com",
            Phone = "(555) 987-6543",
            Address = "123 Business Park Drive\r\nSuite 400\r\nChicago, IL 60601",
            SubscriptionPlan = "Professional"
        };
    }
}

public class Customer
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public string SubscriptionPlan { get; set; }
}
Imports IronPdf
Imports System

Public Class CustomerPortalService
    Public Function GeneratePreFilledRenewalForm(customerId As Integer) As Byte()
        ' Simulate fetching customer data from database
        Dim customer = GetCustomerById(customerId)

        ' Load the renewal form template
        Dim pdf As PdfDocument = PdfDocument.FromFile("templates/subscription-renewal.pdf")

        ' Pre-fill known customer information
        pdf.Form.FindFormField("customerId").Value = customer.Id.ToString()
        pdf.Form.FindFormField("customerName").Value = customer.FullName
        pdf.Form.FindFormField("email").Value = customer.Email
        pdf.Form.FindFormField("phone").Value = customer.Phone
        pdf.Form.FindFormField("address").Value = customer.Address
        pdf.Form.FindFormField("currentPlan").Value = customer.SubscriptionPlan
        pdf.Form.FindFormField("renewalDate").Value = DateTime.Now.AddDays(30).ToString("MM/dd/yyyy")

        ' Leave editable fields empty for customer input:
        ' - newPlan (dropdown for plan selection)
        ' - paymentMethod (radio buttons)
        ' - additionalNotes (textarea)
        ' - signature (signature field)

        ' Return as byte array for web download or email attachment
        Return pdf.BinaryData
    End Function

    ' Simulated data access
    Private Function GetCustomerById(id As Integer) As Customer
        Return New Customer With {
            .Id = id,
            .FullName = "Robert Williams",
            .Email = "robert.williams@email.com",
            .Phone = "(555) 987-6543",
            .Address = "123 Business Park Drive" & vbCrLf & "Suite 400" & vbCrLf & "Chicago, IL 60601",
            .SubscriptionPlan = "Professional"
        }
    End Function
End Class

Public Class Customer
    Public Property Id As Integer
    Public Property FullName As String
    Public Property Email As String
    Public Property Phone As String
    Public Property Address As String
    Public Property SubscriptionPlan As String
End Class
$vbLabelText   $csharpLabel

範例輸出

此模式適用於續約表格、申請更新、年度審核以及系統中已存在部分資訊的任何情況。 使用者會收到一份已填寫好其詳細資料的文檔,只需提供新的或更改的資訊即可。


如何建立表單資料處理管道?

大規模處理表單提交需要結構化的方法,以處理提取、驗證、轉換和儲存。 簡單的流水線模式使這個過程井然有序且易於維護。

using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;

public class FormSubmission
{
    public string SubmissionId { get; set; }
    public DateTime ReceivedAt { get; set; }
    public string SourceFile { get; set; }
    public Dictionary<string, string> FormData { get; set; }
    public bool IsValid { get; set; }
    public List<string> ValidationErrors { get; set; }
}

public class FormProcessingPipeline
{
    public FormSubmission ProcessSubmission(string pdfPath)
    {
        var submission = new FormSubmission
        {
            SubmissionId = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(),
            ReceivedAt = DateTime.UtcNow,
            SourceFile = Path.GetFileName(pdfPath),
            FormData = new Dictionary<string, string>(),
            ValidationErrors = new List<string>()
        };

        // Step 1: Extract form data
        PdfDocument pdf = PdfDocument.FromFile(pdfPath);
        foreach (var field in pdf.Form)
        {
            submission.FormData[field.Name] = field.Value ?? string.Empty;
        }

        // Step 2: Validate required fields
        var requiredFields = new[] { "fullName", "email", "signatureDate" };
        foreach (var fieldName in requiredFields)
        {
            if (!submission.FormData.ContainsKey(fieldName) || 
                string.IsNullOrWhiteSpace(submission.FormData[fieldName]))
            {
                submission.ValidationErrors.Add($"Missing required field: {fieldName}");
            }
        }

        submission.IsValid = submission.ValidationErrors.Count == 0;

        // Step 3: Return the processed submission
        return submission;
    }

    public void ProcessBatch(string folderPath)
    {
        var pdfFiles = Directory.GetFiles(folderPath, "*.pdf");
        var results = new List<FormSubmission>();

        foreach (var file in pdfFiles)
        {
            try
            {
                var submission = ProcessSubmission(file);
                results.Add(submission);
            }
            catch (Exception ex)
            {
                // Handle error for file: ex.Message
            }
        }

        // Summary
        int validCount = 0;
        int invalidCount = 0;
        foreach (var r in results)
        {
            if (r.IsValid) validCount++;
            else invalidCount++;
        }

        // Results summary: results.Count processed, validCount valid, invalidCount invalid
    }
}
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;

public class FormSubmission
{
    public string SubmissionId { get; set; }
    public DateTime ReceivedAt { get; set; }
    public string SourceFile { get; set; }
    public Dictionary<string, string> FormData { get; set; }
    public bool IsValid { get; set; }
    public List<string> ValidationErrors { get; set; }
}

public class FormProcessingPipeline
{
    public FormSubmission ProcessSubmission(string pdfPath)
    {
        var submission = new FormSubmission
        {
            SubmissionId = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(),
            ReceivedAt = DateTime.UtcNow,
            SourceFile = Path.GetFileName(pdfPath),
            FormData = new Dictionary<string, string>(),
            ValidationErrors = new List<string>()
        };

        // Step 1: Extract form data
        PdfDocument pdf = PdfDocument.FromFile(pdfPath);
        foreach (var field in pdf.Form)
        {
            submission.FormData[field.Name] = field.Value ?? string.Empty;
        }

        // Step 2: Validate required fields
        var requiredFields = new[] { "fullName", "email", "signatureDate" };
        foreach (var fieldName in requiredFields)
        {
            if (!submission.FormData.ContainsKey(fieldName) || 
                string.IsNullOrWhiteSpace(submission.FormData[fieldName]))
            {
                submission.ValidationErrors.Add($"Missing required field: {fieldName}");
            }
        }

        submission.IsValid = submission.ValidationErrors.Count == 0;

        // Step 3: Return the processed submission
        return submission;
    }

    public void ProcessBatch(string folderPath)
    {
        var pdfFiles = Directory.GetFiles(folderPath, "*.pdf");
        var results = new List<FormSubmission>();

        foreach (var file in pdfFiles)
        {
            try
            {
                var submission = ProcessSubmission(file);
                results.Add(submission);
            }
            catch (Exception ex)
            {
                // Handle error for file: ex.Message
            }
        }

        // Summary
        int validCount = 0;
        int invalidCount = 0;
        foreach (var r in results)
        {
            if (r.IsValid) validCount++;
            else invalidCount++;
        }

        // Results summary: results.Count processed, validCount valid, invalidCount invalid
    }
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.IO

Public Class FormSubmission
    Public Property SubmissionId As String
    Public Property ReceivedAt As DateTime
    Public Property SourceFile As String
    Public Property FormData As Dictionary(Of String, String)
    Public Property IsValid As Boolean
    Public Property ValidationErrors As List(Of String)
End Class

Public Class FormProcessingPipeline
    Public Function ProcessSubmission(pdfPath As String) As FormSubmission
        Dim submission As New FormSubmission With {
            .SubmissionId = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(),
            .ReceivedAt = DateTime.UtcNow,
            .SourceFile = Path.GetFileName(pdfPath),
            .FormData = New Dictionary(Of String, String)(),
            .ValidationErrors = New List(Of String)()
        }

        ' Step 1: Extract form data
        Dim pdf As PdfDocument = PdfDocument.FromFile(pdfPath)
        For Each field In pdf.Form
            submission.FormData(field.Name) = If(field.Value, String.Empty)
        Next

        ' Step 2: Validate required fields
        Dim requiredFields As String() = {"fullName", "email", "signatureDate"}
        For Each fieldName In requiredFields
            If Not submission.FormData.ContainsKey(fieldName) OrElse
               String.IsNullOrWhiteSpace(submission.FormData(fieldName)) Then
                submission.ValidationErrors.Add($"Missing required field: {fieldName}")
            End If
        Next

        submission.IsValid = submission.ValidationErrors.Count = 0

        ' Step 3: Return the processed submission
        Return submission
    End Function

    Public Sub ProcessBatch(folderPath As String)
        Dim pdfFiles As String() = Directory.GetFiles(folderPath, "*.pdf")
        Dim results As New List(Of FormSubmission)()

        For Each file In pdfFiles
            Try
                Dim submission As FormSubmission = ProcessSubmission(file)
                results.Add(submission)
            Catch ex As Exception
                ' Handle error for file: ex.Message
            End Try
        Next

        ' Summary
        Dim validCount As Integer = 0
        Dim invalidCount As Integer = 0
        For Each r In results
            If r.IsValid Then
                validCount += 1
            Else
                invalidCount += 1
            End If
        Next

        ' Results summary: results.Count processed, validCount valid, invalidCount invalid
    End Sub
End Class
$vbLabelText   $csharpLabel

此管道結構可以擴展,以包含資料庫儲存、電子郵件通知、與外部 API 集成,或您的工作流程所需的任何其他處理步驟。 關鍵在於保持提取、驗證和下游處理之間的分離。

對於高效能批次處理,請參閱非同步 PDF 產生指南,其中涵蓋了多執行緒和平行處理模式。


如何自動產生 IRS 稅務表格,例如 W-9 表格?

政府表格是 PDF 處理量最大的場景之一。 光是 W-9 表格(納稅人識別號碼申請表)每年就有數百萬份被企業用於引進供應商和承包商。 凡是向獨立承包商支付報酬的公司,都需要存檔 W-9 表格,而自動化這個收集過程可以節省大量管理時間。

using IronPdf;
using System;

public class W9FormData
{
    public string Name { get; set; }
    public string BusinessName { get; set; }
    public string FederalTaxClassification { get; set; }
    public string ExemptPayeeCode { get; set; }
    public string FatcaExemptionCode { get; set; }
    public string Address { get; set; }
    public string CityStateZip { get; set; }
    public string AccountNumbers { get; set; }
    public string TaxpayerIdNumber { get; set; }
    public DateTime SignatureDate { get; set; }
}

public class W9FormProcessor
{
    public void FillW9Form(W9FormData data, string templatePath, string outputPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(templatePath);

        // The W-9 form has specific field names defined by the IRS
        // These correspond to the official form structure

        // Line 1: Name as shown on your income tax return
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_1[0]", data.Name);

        // Line 2: Business name/disregarded entity name
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_2[0]", data.BusinessName);

        // Line 3: Federal tax classification (checkbox selection)
        // The W-9 uses checkbox fields for classification
        switch (data.FederalTaxClassification)
        {
            case "Individual":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[0]", "1");
                break;
            case "CCorporation":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[1]", "2");
                break;
            case "SCorporation":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[2]", "3");
                break;
            case "Partnership":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[3]", "4");
                break;
            case "LLC":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[5]", "6");
                break;
        }

        // Line 5: Address
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_7[0]", data.Address);

        // Line 6: City, state, and ZIP code
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_8[0]", data.CityStateZip);

        // Part I: Taxpayer Identification Number (SSN or EIN)
        // For security, typically only last 4 digits are pre-filled or field is left for manual entry
        if (!string.IsNullOrEmpty(data.TaxpayerIdNumber) && data.TaxpayerIdNumber.Length >= 4)
        {
            // TIN left blank for security - user must enter manually
        }

        // Signature date
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Date[0]",
                        data.SignatureDate.ToString("MM/dd/yyyy"));

        pdf.SaveAs(outputPath);
    }

    private void SetFieldIfExists(PdfDocument pdf, string fieldName, string value)
    {
        var field = pdf.Form.FindFormField(fieldName);
        if (field != null && !string.IsNullOrEmpty(value))
        {
            field.Value = value;
        }
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var vendorData = new W9FormData
        {
            Name = "Johnson Consulting LLC",
            BusinessName = "",
            FederalTaxClassification = "LLC",
            Address = "456 Commerce Street",
            CityStateZip = "Austin, TX 78701",
            SignatureDate = DateTime.Today
        };

        var processor = new W9FormProcessor();
        processor.FillW9Form(vendorData, "fw9.pdf", "w9-johnson-consulting.pdf");
    }
}
using IronPdf;
using System;

public class W9FormData
{
    public string Name { get; set; }
    public string BusinessName { get; set; }
    public string FederalTaxClassification { get; set; }
    public string ExemptPayeeCode { get; set; }
    public string FatcaExemptionCode { get; set; }
    public string Address { get; set; }
    public string CityStateZip { get; set; }
    public string AccountNumbers { get; set; }
    public string TaxpayerIdNumber { get; set; }
    public DateTime SignatureDate { get; set; }
}

public class W9FormProcessor
{
    public void FillW9Form(W9FormData data, string templatePath, string outputPath)
    {
        PdfDocument pdf = PdfDocument.FromFile(templatePath);

        // The W-9 form has specific field names defined by the IRS
        // These correspond to the official form structure

        // Line 1: Name as shown on your income tax return
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_1[0]", data.Name);

        // Line 2: Business name/disregarded entity name
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_2[0]", data.BusinessName);

        // Line 3: Federal tax classification (checkbox selection)
        // The W-9 uses checkbox fields for classification
        switch (data.FederalTaxClassification)
        {
            case "Individual":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[0]", "1");
                break;
            case "CCorporation":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[1]", "2");
                break;
            case "SCorporation":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[2]", "3");
                break;
            case "Partnership":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[3]", "4");
                break;
            case "LLC":
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[5]", "6");
                break;
        }

        // Line 5: Address
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_7[0]", data.Address);

        // Line 6: City, state, and ZIP code
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_8[0]", data.CityStateZip);

        // Part I: Taxpayer Identification Number (SSN or EIN)
        // For security, typically only last 4 digits are pre-filled or field is left for manual entry
        if (!string.IsNullOrEmpty(data.TaxpayerIdNumber) && data.TaxpayerIdNumber.Length >= 4)
        {
            // TIN left blank for security - user must enter manually
        }

        // Signature date
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Date[0]",
                        data.SignatureDate.ToString("MM/dd/yyyy"));

        pdf.SaveAs(outputPath);
    }

    private void SetFieldIfExists(PdfDocument pdf, string fieldName, string value)
    {
        var field = pdf.Form.FindFormField(fieldName);
        if (field != null && !string.IsNullOrEmpty(value))
        {
            field.Value = value;
        }
    }
}

// Usage example
class Program
{
    static void Main()
    {
        var vendorData = new W9FormData
        {
            Name = "Johnson Consulting LLC",
            BusinessName = "",
            FederalTaxClassification = "LLC",
            Address = "456 Commerce Street",
            CityStateZip = "Austin, TX 78701",
            SignatureDate = DateTime.Today
        };

        var processor = new W9FormProcessor();
        processor.FillW9Form(vendorData, "fw9.pdf", "w9-johnson-consulting.pdf");
    }
}
Imports IronPdf
Imports System

Public Class W9FormData
    Public Property Name As String
    Public Property BusinessName As String
    Public Property FederalTaxClassification As String
    Public Property ExemptPayeeCode As String
    Public Property FatcaExemptionCode As String
    Public Property Address As String
    Public Property CityStateZip As String
    Public Property AccountNumbers As String
    Public Property TaxpayerIdNumber As String
    Public Property SignatureDate As DateTime
End Class

Public Class W9FormProcessor
    Public Sub FillW9Form(data As W9FormData, templatePath As String, outputPath As String)
        Dim pdf As PdfDocument = PdfDocument.FromFile(templatePath)

        ' The W-9 form has specific field names defined by the IRS
        ' These correspond to the official form structure

        ' Line 1: Name as shown on your income tax return
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_1[0]", data.Name)

        ' Line 2: Business name/disregarded entity name
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].f1_2[0]", data.BusinessName)

        ' Line 3: Federal tax classification (checkbox selection)
        ' The W-9 uses checkbox fields for classification
        Select Case data.FederalTaxClassification
            Case "Individual"
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[0]", "1")
            Case "CCorporation"
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[1]", "2")
            Case "SCorporation"
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[2]", "3")
            Case "Partnership"
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[3]", "4")
            Case "LLC"
                SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].FederalClassification[0].c1_1[5]", "6")
        End Select

        ' Line 5: Address
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_7[0]", data.Address)

        ' Line 6: City, state, and ZIP code
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Address[0].f1_8[0]", data.CityStateZip)

        ' Part I: Taxpayer Identification Number (SSN or EIN)
        ' For security, typically only last 4 digits are pre-filled or field is left for manual entry
        If Not String.IsNullOrEmpty(data.TaxpayerIdNumber) AndAlso data.TaxpayerIdNumber.Length >= 4 Then
            ' TIN left blank for security - user must enter manually
        End If

        ' Signature date
        SetFieldIfExists(pdf, "topmostSubform[0].Page1[0].Date[0]", data.SignatureDate.ToString("MM/dd/yyyy"))

        pdf.SaveAs(outputPath)
    End Sub

    Private Sub SetFieldIfExists(pdf As PdfDocument, fieldName As String, value As String)
        Dim field = pdf.Form.FindFormField(fieldName)
        If field IsNot Nothing AndAlso Not String.IsNullOrEmpty(value) Then
            field.Value = value
        End If
    End Sub
End Class

' Usage example
Module Program
    Sub Main()
        Dim vendorData As New W9FormData With {
            .Name = "Johnson Consulting LLC",
            .BusinessName = "",
            .FederalTaxClassification = "LLC",
            .Address = "456 Commerce Street",
            .CityStateZip = "Austin, TX 78701",
            .SignatureDate = DateTime.Today
        }

        Dim processor As New W9FormProcessor()
        processor.FillW9Form(vendorData, "fw9.pdf", "w9-johnson-consulting.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

政府表格通常使用複雜的層級式欄位命名規則。 上面顯示的 W-9 欄位名稱遵循美國國稅局官方 PDF 中使用的 XFA 衍生命名模式。 使用政府表格時,請務必從官方機構網站下載最新版本,並在編寫自動化程式碼之前檢查其欄位結構。


如何批次處理包含可變資料的表單?

批次處理從資料庫查詢、CSV 檔案或 API 回應等資料來源產生多個已完成的表單。 這項功能對於諸如年度稅務文件分發、員工入職資料包或客戶報表產生等場景至關重要。

using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

public class VendorRecord
{
    public string VendorId { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string TaxClassification { get; set; }
}

public class BatchFormGenerator
{
    private readonly string _templatePath;
    private readonly string _outputDirectory;

    public BatchFormGenerator(string templatePath, string outputDirectory)
    {
        _templatePath = templatePath;
        _outputDirectory = outputDirectory;

        if (!Directory.Exists(_outputDirectory))
        {
            Directory.CreateDirectory(_outputDirectory);
        }
    }

    public void GenerateVendorForms(List<VendorRecord> vendors)
    {
        var startTime = DateTime.Now;
        int successCount = 0;
        int errorCount = 0;

        foreach (var vendor in vendors)
        {
            try
            {
                GenerateSingleForm(vendor);
                successCount++;
            }
            catch (Exception ex)
            {
                errorCount++;
                // Handle error: ex.Message
            }
        }

        var elapsed = DateTime.Now - startTime;
        // Results: successCount successful, errorCount errors, elapsed time
    }

    private void GenerateSingleForm(VendorRecord vendor)
    {
        PdfDocument pdf = PdfDocument.FromFile(_templatePath);

        // Fill vendor information fields
        SetField(pdf, "vendorId", vendor.VendorId);
        SetField(pdf, "companyName", vendor.CompanyName);
        SetField(pdf, "contactName", vendor.ContactName);
        SetField(pdf, "address", vendor.Address);
        SetField(pdf, "city", vendor.City);
        SetField(pdf, "state", vendor.State);
        SetField(pdf, "zipCode", vendor.ZipCode);
        SetField(pdf, "taxClassification", vendor.TaxClassification);
        SetField(pdf, "generatedDate", DateTime.Today.ToString("MM/dd/yyyy"));

        // Create a safe filename from company name
        string safeFileName = string.Join("_", vendor.CompanyName.Split(Path.GetInvalidFileNameChars()));
        string outputPath = Path.Combine(_outputDirectory, $"vendor-form-{vendor.VendorId}-{safeFileName}.pdf");

        pdf.SaveAs(outputPath);
    }

    private void SetField(PdfDocument pdf, string fieldName, string value)
    {
        var field = pdf.Form.FindFormField(fieldName);
        if (field != null)
        {
            field.Value = value ?? string.Empty;
        }
    }
}

// Usage example with sample data
class Program
{
    static void Main()
    {
        var vendors = new List<VendorRecord>
        {
            new VendorRecord
            {
                VendorId = "V001",
                CompanyName = "Alpha Supplies Inc",
                ContactName = "Maria Garcia",
                Address = "100 Industrial Way",
                City = "Chicago",
                State = "IL",
                ZipCode = "60601",
                TaxClassification = "Corporation"
            },
            new VendorRecord
            {
                VendorId = "V002",
                CompanyName = "Beta Services LLC",
                ContactName = "James Wilson",
                Address = "200 Tech Park Drive",
                City = "Austin",
                State = "TX",
                ZipCode = "78701",
                TaxClassification = "LLC"
            },
            new VendorRecord
            {
                VendorId = "V003",
                CompanyName = "Gamma Consulting",
                ContactName = "Sarah Chen",
                Address = "300 Business Center",
                City = "Seattle",
                State = "WA",
                ZipCode = "98101",
                TaxClassification = "Partnership"
            }
        };

        var generator = new BatchFormGenerator("vendor-info-template.pdf", "output/vendor-forms");
        generator.GenerateVendorForms(vendors);
    }
}
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

public class VendorRecord
{
    public string VendorId { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string TaxClassification { get; set; }
}

public class BatchFormGenerator
{
    private readonly string _templatePath;
    private readonly string _outputDirectory;

    public BatchFormGenerator(string templatePath, string outputDirectory)
    {
        _templatePath = templatePath;
        _outputDirectory = outputDirectory;

        if (!Directory.Exists(_outputDirectory))
        {
            Directory.CreateDirectory(_outputDirectory);
        }
    }

    public void GenerateVendorForms(List<VendorRecord> vendors)
    {
        var startTime = DateTime.Now;
        int successCount = 0;
        int errorCount = 0;

        foreach (var vendor in vendors)
        {
            try
            {
                GenerateSingleForm(vendor);
                successCount++;
            }
            catch (Exception ex)
            {
                errorCount++;
                // Handle error: ex.Message
            }
        }

        var elapsed = DateTime.Now - startTime;
        // Results: successCount successful, errorCount errors, elapsed time
    }

    private void GenerateSingleForm(VendorRecord vendor)
    {
        PdfDocument pdf = PdfDocument.FromFile(_templatePath);

        // Fill vendor information fields
        SetField(pdf, "vendorId", vendor.VendorId);
        SetField(pdf, "companyName", vendor.CompanyName);
        SetField(pdf, "contactName", vendor.ContactName);
        SetField(pdf, "address", vendor.Address);
        SetField(pdf, "city", vendor.City);
        SetField(pdf, "state", vendor.State);
        SetField(pdf, "zipCode", vendor.ZipCode);
        SetField(pdf, "taxClassification", vendor.TaxClassification);
        SetField(pdf, "generatedDate", DateTime.Today.ToString("MM/dd/yyyy"));

        // Create a safe filename from company name
        string safeFileName = string.Join("_", vendor.CompanyName.Split(Path.GetInvalidFileNameChars()));
        string outputPath = Path.Combine(_outputDirectory, $"vendor-form-{vendor.VendorId}-{safeFileName}.pdf");

        pdf.SaveAs(outputPath);
    }

    private void SetField(PdfDocument pdf, string fieldName, string value)
    {
        var field = pdf.Form.FindFormField(fieldName);
        if (field != null)
        {
            field.Value = value ?? string.Empty;
        }
    }
}

// Usage example with sample data
class Program
{
    static void Main()
    {
        var vendors = new List<VendorRecord>
        {
            new VendorRecord
            {
                VendorId = "V001",
                CompanyName = "Alpha Supplies Inc",
                ContactName = "Maria Garcia",
                Address = "100 Industrial Way",
                City = "Chicago",
                State = "IL",
                ZipCode = "60601",
                TaxClassification = "Corporation"
            },
            new VendorRecord
            {
                VendorId = "V002",
                CompanyName = "Beta Services LLC",
                ContactName = "James Wilson",
                Address = "200 Tech Park Drive",
                City = "Austin",
                State = "TX",
                ZipCode = "78701",
                TaxClassification = "LLC"
            },
            new VendorRecord
            {
                VendorId = "V003",
                CompanyName = "Gamma Consulting",
                ContactName = "Sarah Chen",
                Address = "300 Business Center",
                City = "Seattle",
                State = "WA",
                ZipCode = "98101",
                TaxClassification = "Partnership"
            }
        };

        var generator = new BatchFormGenerator("vendor-info-template.pdf", "output/vendor-forms");
        generator.GenerateVendorForms(vendors);
    }
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.IO

Public Class VendorRecord
    Public Property VendorId As String
    Public Property CompanyName As String
    Public Property ContactName As String
    Public Property Address As String
    Public Property City As String
    Public Property State As String
    Public Property ZipCode As String
    Public Property TaxClassification As String
End Class

Public Class BatchFormGenerator
    Private ReadOnly _templatePath As String
    Private ReadOnly _outputDirectory As String

    Public Sub New(templatePath As String, outputDirectory As String)
        _templatePath = templatePath
        _outputDirectory = outputDirectory

        If Not Directory.Exists(_outputDirectory) Then
            Directory.CreateDirectory(_outputDirectory)
        End If
    End Sub

    Public Sub GenerateVendorForms(vendors As List(Of VendorRecord))
        Dim startTime = DateTime.Now
        Dim successCount As Integer = 0
        Dim errorCount As Integer = 0

        For Each vendor In vendors
            Try
                GenerateSingleForm(vendor)
                successCount += 1
            Catch ex As Exception
                errorCount += 1
                ' Handle error: ex.Message
            End Try
        Next

        Dim elapsed = DateTime.Now - startTime
        ' Results: successCount successful, errorCount errors, elapsed time
    End Sub

    Private Sub GenerateSingleForm(vendor As VendorRecord)
        Dim pdf As PdfDocument = PdfDocument.FromFile(_templatePath)

        ' Fill vendor information fields
        SetField(pdf, "vendorId", vendor.VendorId)
        SetField(pdf, "companyName", vendor.CompanyName)
        SetField(pdf, "contactName", vendor.ContactName)
        SetField(pdf, "address", vendor.Address)
        SetField(pdf, "city", vendor.City)
        SetField(pdf, "state", vendor.State)
        SetField(pdf, "zipCode", vendor.ZipCode)
        SetField(pdf, "taxClassification", vendor.TaxClassification)
        SetField(pdf, "generatedDate", DateTime.Today.ToString("MM/dd/yyyy"))

        ' Create a safe filename from company name
        Dim safeFileName As String = String.Join("_", vendor.CompanyName.Split(Path.GetInvalidFileNameChars()))
        Dim outputPath As String = Path.Combine(_outputDirectory, $"vendor-form-{vendor.VendorId}-{safeFileName}.pdf")

        pdf.SaveAs(outputPath)
    End Sub

    Private Sub SetField(pdf As PdfDocument, fieldName As String, value As String)
        Dim field = pdf.Form.FindFormField(fieldName)
        If field IsNot Nothing Then
            field.Value = If(value, String.Empty)
        End If
    End Sub
End Class

' Usage example with sample data
Module Program
    Sub Main()
        Dim vendors As New List(Of VendorRecord) From {
            New VendorRecord With {
                .VendorId = "V001",
                .CompanyName = "Alpha Supplies Inc",
                .ContactName = "Maria Garcia",
                .Address = "100 Industrial Way",
                .City = "Chicago",
                .State = "IL",
                .ZipCode = "60601",
                .TaxClassification = "Corporation"
            },
            New VendorRecord With {
                .VendorId = "V002",
                .CompanyName = "Beta Services LLC",
                .ContactName = "James Wilson",
                .Address = "200 Tech Park Drive",
                .City = "Austin",
                .State = "TX",
                .ZipCode = "78701",
                .TaxClassification = "LLC"
            },
            New VendorRecord With {
                .VendorId = "V003",
                .CompanyName = "Gamma Consulting",
                .ContactName = "Sarah Chen",
                .Address = "300 Business Center",
                .City = "Seattle",
                .State = "WA",
                .ZipCode = "98101",
                .TaxClassification = "Partnership"
            }
        }

        Dim generator As New BatchFormGenerator("vendor-info-template.pdf", "output/vendor-forms")
        generator.GenerateVendorForms(vendors)
    End Sub
End Module
$vbLabelText   $csharpLabel

對於非常大的批次,可以考慮採用可控並發的平行處理來最大限度地提高吞吐量,而不會使系統資源不堪重負。


如何確保符合政府PDF標準?

政府機構通常要求文件符合特定的 PDF 標準,以便長期存檔和存取。 PDF/A 是 PDF 的一個 ISO 標準化子集,旨在可靠地長期保存電子文件。 IronPDF 支援以 PDF/A 格式匯出文檔,以滿足這些合規性要求。

以下程式碼從 HTML 建立官方政府表格,用申請人資料填入表格,並使用SaveAsPdfA()方法將其儲存為符合 PDF/A-3b 標準的文件。 這種格式確保文件在未來幾十年內仍然可讀,並滿足大多數政府提交要求。

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-forms-csharp/pdfa-compliance.cs
using IronPdf;

// Create or load a form document
string formHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        h1 { color: #003366; }
        .form-section { margin: 20px 0; }
        label { display: block; margin: 10px 0 5px 0; font-weight: bold; }
        input, select { padding: 8px; width: 300px; border: 1px solid #ccc; }
    </style>
</head>
<body>
    <h1>Official Government Form</h1>
    <p>This document complies with PDF/A-3b archival standards.</p>
    <form>
        <div class='form-section'>
            <label>Applicant Name</label>
            <input type='text' name='applicantName' />
        </div>
        <div class='form-section'>
            <label>Application Date</label>
            <input type='text' name='applicationDate' />
        </div>
        <div class='form-section'>
            <label>Department</label>
            <select name='department'>
                <option value=''>Select Department</option>
                <option value='Revenue'>Department of Revenue</option>
                <option value='Labor'>Department of Labor</option>
                <option value='Commerce'>Department of Commerce</option>
            </select>
        </div>
    </form>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

PdfDocument pdf = renderer.RenderHtmlAsPdf(formHtml);

// Fill form fields
pdf.Form.FindFormField("applicantName").Value = "Government Services Corp";
pdf.Form.FindFormField("applicationDate").Value = DateTime.Today.ToString("MM/dd/yyyy");
pdf.Form.FindFormField("department").Value = "Commerce";

// Convert to PDF/A-3b for archival compliance
pdf.SaveAsPdfA("government-form-archived.pdf", PdfAVersions.PdfA3b);
Imports IronPdf

' Create or load a form document
Dim formHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        h1 { color: #003366; }
        .form-section { margin: 20px 0; }
        label { display: block; margin: 10px 0 5px 0; font-weight: bold; }
        input, select { padding: 8px; width: 300px; border: 1px solid #ccc; }
    </style>
</head>
<body>
    <h1>Official Government Form</h1>
    <p>This document complies with PDF/A-3b archival standards.</p>
    <form>
        <div class='form-section'>
            <label>Applicant Name</label>
            <input type='text' name='applicantName' />
        </div>
        <div class='form-section'>
            <label>Application Date</label>
            <input type='text' name='applicationDate' />
        </div>
        <div class='form-section'>
            <label>Department</label>
            <select name='department'>
                <option value=''>Select Department</option>
                <option value='Revenue'>Department of Revenue</option>
                <option value='Labor'>Department of Labor</option>
                <option value='Commerce'>Department of Commerce</option>
            </select>
        </div>
    </form>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(formHtml)

' Fill form fields
pdf.Form.FindFormField("applicantName").Value = "Government Services Corp"
pdf.Form.FindFormField("applicationDate").Value = DateTime.Today.ToString("MM/dd/yyyy")
pdf.Form.FindFormField("department").Value = "Commerce"

' Convert to PDF/A-3b for archival compliance
pdf.SaveAsPdfA("government-form-archived.pdf", PdfAVersions.PdfA3b)
$vbLabelText   $csharpLabel

範例輸出

SaveAsPdfA()方法接受輸出檔名和PdfAVersions枚舉值(例如PdfA3b )。 在儲存過程中,IronPDF 會自動嵌入所有字體,標準化色彩空間,移除任何加密,並根據 PDF/A 要求建立元資料。 這些轉換確保即使在未來幾十年內,無論使用什麼軟體嘗試打開,文件仍然可讀且視覺效果相同。

向政府機構提交表格時,請查閱其具體要求。 有些文件可能要求使用 PDF/A-1b 進行基本歸檔,而有些文件則指定使用 PDF/A-3b 以允許嵌入 XML 資料檔等附件。 例如,美國國稅局接受特定格式的 PDF 文件用於不同的提交類型,而移民表格通常也有自己的技術規格。

有關完整的 PDF/A 轉換文檔,請參閱C# 中的"將 PDF 轉換為 PDF/A-3b"PDF/A 合規性指南。 有關無障礙標準,請參閱建立 PDF/UA 文件


後續步驟

現在您已經擁有了自動化那些耗費數小時手動資料輸入的 PDF 表單工作流程所需的一切。 無論您是在處理供應商入職所需的 W-9 表格、從 EHR 系統預填患者入院表格,還是將提交的申請資料匯入 CRM,本指南中的技巧都可直接應用於您收件匣中正在處理的表格。 若要全面了解表單以外的 PDF 編輯功能,請參閱PDF 編輯教學

要繼續前進,首先填寫並編輯團隊已在使用的現有表單,例如客戶申請表或員工入職資料包,並按照本指南中的字典方法建立一個簡單的流程。之後,您可以利用 HTML 建立新表單以獲得完全的設計彈性,或為需要具有法律約束力的簽字的表單新增數位簽章欄位。 當您需要符合政府存檔標準時, PDF/A 合規指南涵蓋長期保存,而PDF/UA 可訪問性指南可確保您的表單通過第 508 節審核。

準備開始建造了嗎? 下載 IronPDF並免費試用。 同一個庫可以處理從單一表單填寫到跨 .NET 環境的大批量處理的所有任務。 如果您對表單自動化或整合有任何疑問,請聯絡我們的工程支援團隊


常見問題解答

如何使用C#建立PDF表單?

您可以使用 IronPDF 將 HTML 表單轉換為 PDF 文檔,從而在 C# 中建立 PDF 表單。這使得互動式表單的自訂和設計變得輕鬆便捷。

是否可以使用 C# 以程式方式填入現有的 PDF 表單?

是的,IronPDF 允許您使用 C# 程式碼存取和修改表單字段,從而以程式設計方式在 C# 中填寫現有的 PDF 表單。

我可以使用 IronPDF 從 PDF 表單中提取數據嗎?

IronPDF 提供從 PDF 文件中提取表單資料的功能,使用戶能夠輕鬆檢索和處理在 PDF 表單中輸入的資訊。

將PDF表單展平意味著什麼?

扁平化 PDF 表單是指將表單欄位轉換為靜態內容,從而阻止後續編輯。 IronPDF 可以扁平化表單,以確保資料完整性並防止表單提交後發生變更。

如何實現政府表格(例如 W-9 表格)的自動化處理?

IronPDF 可以自動處理 W-9 等政府表格,讓您能夠以程式設計方式填寫、擷取和管理表單數據,從而簡化您的工作流程。

使用HTML建立PDF表單有哪些優勢?

使用 HTML 和 IronPDF 建立 PDF 表單,可以實現設計上的靈活性和與現有 Web 技術的輕鬆集成,從而建立動態和響應式表單。

IronPDF 能否處理互動式表單元素?

是的,IronPDF 支援互動式表單元素,例如文字欄位、核取方塊和按鈕,從而可以在 C# 中建立和操作動態 PDF 表單。

是否可以自訂PDF表單的外觀?

IronPDF 允許對 PDF 表單的外觀進行完全自訂,可讓您將 CSS 樣式套用至表單元素,從而獲得專業且一致的外觀。

Curtis Chau
技術撰稿人

Curtis Chau 擁有電腦科學學士學位(卡爾頓大學),專長於前端開發,精通 Node.js、TypeScript、JavaScript 和 React。Curtis 對製作直覺且美觀的使用者介面充滿熱情,他喜歡使用現代化的架構,並製作結構良好且視覺上吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 也有濃厚的興趣,他喜歡探索整合硬體與軟體的創新方式。在空閒時間,他喜歡玩遊戲和建立 Discord bots,將他對技術的熱愛與創意結合。

準備好開始了嗎?
Nuget 下載 17,386,124 | 版本: 2026.2 剛剛發布