当前位置: 首页 > news >正文

C# 操作PDF表单 - 创建、填写、删除PDF表单域

通常情况下,PDF文件是不可编辑的,但PDF表单提供了一些可编辑区域,允许用户填写和提交信息。PDF表单通常用于收集信息、反馈或进行在线申请,是许多行业中数据收集和交换的重要工具。

PDF表单可以包含各种类型的输入控件,如文本框、复选框、下拉菜单、单选按钮等。本文将介绍如何使用C# 和一个免费.NET库来操作PDF表单,包括以下三个示例:

目录

使用C# 创建PDF表单域

使用C# 填写PDF表单域

使用C# 删除PDF表单域


安装免费.NET PDF库 Free Spire.PDF for .NET (可通过 NuGet安装,或下载后手动引用dll

PM> Install-Package FreeSpire.PDF

常见PDF表单域

Free Spire.PDF for .NET 支持创建、操作多种PDF表域,包括文本框、复选框、组合框、列表框和单选按钮等。下表列出了一些常见的域及其在该免费库中对应的类名。

表单域名类名
文本域PdfTextBoxField
复选框PdfCheckBoxField
组合框PdfComboBoxField
列表框PdfListBoxField
单选按钮PdfRadioButtonListField
普通按钮PdfButtonField
签名域PdfSignatureField

使用C# 创建PDF表单域

使用Free Spire.PDF制作表单域,需要先创建以上各表单域类的对象,然后通过 Bounds 属性设置表单域的位置和大小,最后再通过PdfFormFieldCollection.Add() 方法将表单域绘制到PDF页面指定位置处。

以下是如何在PDF中创建上述常见PDF表单域的C#代码:

using Spire.Pdf;
using Spire.Pdf.Actions;
using Spire.Pdf.Fields;
using Spire.Pdf.Graphics;
using System.Drawing;namespace CreateFillableFormsInPdf
{class Program{static void Main(string[] args){//创建PdfDocument对象PdfDocument pdf = new PdfDocument();//添加一页PdfPageBase page = pdf.Pages.Add();//初始化x、y坐标float baseX = 60;float baseY = 20;//创建两个画刷PdfSolidBrush brush1 = new PdfSolidBrush(new PdfRGBColor(Color.Brown));PdfSolidBrush brush2 = new PdfSolidBrush(new PdfRGBColor(Color.Black));//创建字体PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("微软雅黑", 11f, FontStyle.Regular), true);//添加文本框 page.Canvas.DrawString("姓名:", font, brush1, new PointF(10, baseY));RectangleF tbxBounds = new RectangleF(baseX, baseY, 150, 18);PdfTextBoxField textBox = new PdfTextBoxField(page, "姓名");textBox.Bounds = tbxBounds;textBox.Font = font;pdf.Form.Fields.Add(textBox);baseY += 30;//添加两个复选框page.Canvas.DrawString("民族:", font, brush1, new PointF(10, baseY));RectangleF checkboxBound1 = new RectangleF(baseX, baseY, 15, 15);PdfCheckBoxField checkBoxField1 = new PdfCheckBoxField(page, "选项1");checkBoxField1.Bounds = checkboxBound1;checkBoxField1.Checked = false;page.Canvas.DrawString("汉族", font, brush2, new PointF(baseX + 20, baseY));RectangleF checkboxBound2 = new RectangleF(baseX + 70, baseY, 15, 15);PdfCheckBoxField checkBoxField2 = new PdfCheckBoxField(page, "选项2");checkBoxField2.Bounds = checkboxBound2;checkBoxField2.Checked = false;page.Canvas.DrawString("少数民族", font, brush2, new PointF(baseX + 90, baseY));pdf.Form.Fields.Add(checkBoxField1);pdf.Form.Fields.Add(checkBoxField2);baseY += 30;//添加列表框page.Canvas.DrawString("分公司:", font, brush1, new PointF(10, baseY));RectangleF listboxBound = new RectangleF(baseX, baseY, 150, 50);PdfListBoxField listBoxField = new PdfListBoxField(page, "分公司");listBoxField.Items.Add(new PdfListFieldItem("成都", "成都"));listBoxField.Items.Add(new PdfListFieldItem("武汉", "武汉"));listBoxField.Items.Add(new PdfListFieldItem("深圳", "深圳")); ;listBoxField.Bounds = listboxBound;listBoxField.Font = font;pdf.Form.Fields.Add(listBoxField);baseY += 60;//添加两个单选按钮page.Canvas.DrawString("性别:", font, brush1, new PointF(10, baseY));PdfRadioButtonListField radioButtonListField = new PdfRadioButtonListField(page, "性别");PdfRadioButtonListItem radioItem1 = new PdfRadioButtonListItem("选项1");RectangleF radioBound1 = new RectangleF(baseX, baseY, 15, 15);radioItem1.Bounds = radioBound1;page.Canvas.DrawString("男", font, brush2, new PointF(baseX + 20, baseY));PdfRadioButtonListItem radioItem2 = new PdfRadioButtonListItem("选项2");RectangleF radioBound2 = new RectangleF(baseX + 70, baseY, 15, 15);radioItem2.Bounds = radioBound2;page.Canvas.DrawString("女", font, brush2, new PointF(baseX + 90, baseY));radioButtonListField.Items.Add(radioItem1);radioButtonListField.Items.Add(radioItem2);pdf.Form.Fields.Add(radioButtonListField);baseY += 30;//添加组合框page.Canvas.DrawString("部门:", font, brush1, new PointF(10, baseY));RectangleF cmbBounds = new RectangleF(baseX, baseY, 150, 18);PdfComboBoxField comboBoxField = new PdfComboBoxField(page, "部门");comboBoxField.Bounds = cmbBounds;comboBoxField.Items.Add(new PdfListFieldItem("财务", "财务"));comboBoxField.Items.Add(new PdfListFieldItem("技术", "技术"));comboBoxField.Items.Add(new PdfListFieldItem("采购", "采购"));comboBoxField.Items.Add(new PdfListFieldItem("销售", "销售"));comboBoxField.Font = font;pdf.Form.Fields.Add(comboBoxField);baseY += 30;//添加签名域page.Canvas.DrawString("签名:", font, brush1, new PointF(10, baseY));PdfSignatureField sgnField = new PdfSignatureField(page, "签名域");RectangleF sgnBounds = new RectangleF(baseX, baseY, 150, 80);sgnField.Bounds = sgnBounds;pdf.Form.Fields.Add(sgnField);baseY += 90;//添加按钮page.Canvas.DrawString("按钮:", font, brush1, new PointF(10, baseY));RectangleF btnBounds = new RectangleF(baseX, baseY, 50, 18);PdfButtonField buttonField = new PdfButtonField(page, "按钮");buttonField.Bounds = btnBounds;buttonField.Text = "提交";buttonField.Font = font;PdfSubmitAction submitAction = new PdfSubmitAction("https://www.****.com");submitAction.DataFormat = SubmitDataFormat.Html;buttonField.Actions.MouseDown = submitAction;pdf.Form.Fields.Add(buttonField);//保存文件pdf.SaveToFile("PDF表单.pdf", FileFormat.PDF);}}
}

生成文件:

使用C# 填写PDF表单域

填充表单域需要先获取PDF中的所有表单字段,然后确定其表单类型,最后再填写数据或从预定列表中选择值。

以下是如何填充现有PDF表单域的C#代码:

using Spire.Pdf;
using Spire.Pdf.Fields;
using Spire.Pdf.Widget;namespace FillFormFields
{class Program{static void Main(string[] args){//加载PDF表单PdfDocument pdf = new PdfDocument();pdf.LoadFromFile("PDF表单.pdf");//获取文档中的表单PdfFormWidget form = (PdfFormWidget)pdf.Form;//获取表单域集合PdfFormFieldWidgetCollection formWidgetCollection = form.FieldsWidget;//遍历表单域for (int i = 0; i < formWidgetCollection.Count; i++){//获取指定域PdfField field = formWidgetCollection[i];//判断该表单域是否为文本框if (field is PdfTextBoxFieldWidget){if (field.Name == "姓名"){//填充文本PdfTextBoxFieldWidget textBoxField = (PdfTextBoxFieldWidget)field;textBoxField.Text = "张三";}}//判断该表单域是否为单选按钮if (field is PdfRadioButtonListFieldWidget){if (field.Name == "性别"){//为单选按钮选定一个值PdfRadioButtonListFieldWidget radioButtonListField = (PdfRadioButtonListFieldWidget)field;radioButtonListField.SelectedIndex = 0;}}//判断该表单域是否为组合框if (field is PdfComboBoxWidgetFieldWidget){if (field.Name == "部门"){//为组合框选定一个值PdfComboBoxWidgetFieldWidget comboBoxField = (PdfComboBoxWidgetFieldWidget)field;int[] index = { 1 };comboBoxField.SelectedIndex = index;}}//判断该表单域是否为复选框if (field is PdfCheckBoxWidgetFieldWidget){//设置复选框的"已选中"状态PdfCheckBoxWidgetFieldWidget checkBoxField = (PdfCheckBoxWidgetFieldWidget)field;switch (checkBoxField.Name){case "选项1":checkBoxField.Checked = true;break;}}//判断该表单域是否为列表框if (field is PdfListBoxWidgetFieldWidget){if (field.Name == "分公司"){//为列表框选定一个值PdfListBoxWidgetFieldWidget listBox = (PdfListBoxWidgetFieldWidget)field;int[] index = { 1 };listBox.SelectedIndex = index;}}}//保存文件pdf.SaveToFile("填充PDF表单域.pdf", FileFormat.PDF);}}
}

输出结果:

 

使用C# 删除PDF表单域

Free Spire.PDF支持通过索引或名称删除指定的表单域或删除所有表单域。

以下是如何删除PDF表单域的C#代码:

using Spire.Pdf;
using Spire.Pdf.Fields;
using Spire.Pdf.Widget;namespace RemoveFormFields
{class Program{static void Main(string[] args){//加载PDF表单PdfDocument pdf = new PdfDocument();pdf.LoadFromFile("PDF表单.pdf");//获取文档中的表单域PdfFormWidget formWidget = pdf.Form as PdfFormWidget;//遍历表单域for (int i = formWidget.FieldsWidget.List.Count - 1; i >= 0; i--){//获取指定表单域PdfField field = formWidget.FieldsWidget.List[i] as PdfField;//删除表单域formWidget.FieldsWidget.Remove(field);}//通过表单域名获取指定表单//PdfField field = formWidget.FieldsWidget["name"];//删除该表单域//formWidget.FieldsWidget.Remove(field);//保存PDF文件pdf.SaveToFile("删除PDF表单域.pdf");}}
}

以上代码演示了PDF表单的基本操作,包括添加文本框、复选框、组合框、单选按钮等各种常见的表单域,填写现有PDF表单,以及删除PDF表单。Free Spire.PDF免费库该支持其他多种PDF元素,点击查看更多示例。

相关文章:

C# 操作PDF表单 - 创建、填写、删除PDF表单域

通常情况下&#xff0c;PDF文件是不可编辑的&#xff0c;但PDF表单提供了一些可编辑区域&#xff0c;允许用户填写和提交信息。PDF表单通常用于收集信息、反馈或进行在线申请&#xff0c;是许多行业中数据收集和交换的重要工具。 PDF表单可以包含各种类型的输入控件&#xff0…...

Astropy:探索宇宙奥秘的Python工具箱

Astropy:探索宇宙奥秘的Python工具箱 什么是Astropy库&#xff1f; Astropy 是一个面向天文学领域的 Python 库&#xff0c;旨在提供常用的天文学数据结构、单位转换、物理常数以及天文学计算方法等功能。它为天文学家和研究人员提供了丰富的工具&#xff0c;用于处理和分析天文…...

java数据结构与算法刷题-----LeetCode684. 冗余连接

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 并查集 并查集 解题思路&#xff1a;时间复杂度O( n ∗ l o g 2…...

循环神经网络简介

卷积神经网络相当于人类的视觉&#xff0c;但是它并没有记忆能力&#xff0c;所以它只能处理一种特定的视觉任务&#xff0c;没办法根据以前的记忆来处理新的任务。比如&#xff0c;在一场电影中推断下一个时间点的场景&#xff0c;这个时候仅依赖于现在的场景还不够&#xff0…...

计算机网络 子网掩码与划分子网

一、实验要求与内容 1、需拓扑图和两个主机的IP配置截图。 2、设置网络A内的主机IP地址为“192.168.班内学号.2”&#xff0c;子网掩码为“255.255.255.128”&#xff0c;网关为“192.168.班内学号.1”&#xff1b;设置网络B内的主机IP地址为“192.168.班内学号100.2”&#…...

HUD抬头显示器中如何设计LCD的阳光倒灌实验

关键词&#xff1a;阳光倒灌实验、HUD光照温升测试、LCD光照温升测试、太阳光模拟器 HUD&#xff08;Head-Up Display&#xff0c;即抬头显示器&#xff09;是一种将信息直接投影到驾驶员视线中的技术&#xff0c;通常用于飞机、汽车等驾驶舱内。HUD系统中的LCD&#xff08;Liq…...

Shoplazza闪耀Shoptalk 2024,新零售创新解决方案引领行业新篇章!

在近期举办的全球零售业瞩目盛事——Shoptalk 2024大会上,全球*的零售技术平台-店匠科技(Shoplazza)以其*的创新实力与前瞻的技术理念,成功吸引了与会者的广泛关注。此次盛会于3月17日至20日在拉斯维加斯曼德勒湾隆重举行,汇聚了逾万名行业精英。在这场零售业的盛大聚会上,Shop…...

Linux:sprintf、snprintf、vsprintf、asprintf、vasprintf比较

这些函数都在stdio.h里&#xff0c;不过不同系统不同库&#xff0c;有些函数不一定提供。 1. sprintf 函数原型&#xff1a; int sprintf (char *str, const char *format, ...); extern int sprintf (char *__restrict __s, const char *__restrict __format, ...); 功能是将…...

Github远程仓库改名字之后,本地git如何配置?

文章目录 缘由解决方案 缘由 今天在github创建一个仓库&#xff0c;备份一下本地电脑上的资料。起初随便起一个仓库名字&#xff0c;后来修改之。既然远程仓库改名&#xff0c;那么本地仓库需要更新地址。这里采用SSH格式。 解决方案 如果你的GitHub仓库改名了&#xff0c;你…...

Objective-C学习笔记(ARC,分类,延展)4.10

1.自动释放池autoreleasepool&#xff1a;存入到自动释放池的对象&#xff0c;在自动释放池销毁时&#xff0c;会自动调用池内所有对象的release方法。调用autorelease方法将对象放入自动释放池。 Person *p1 [ [ [ Person alloc ] init ] autorelease]; 2.在类方法里写一个…...

02 Git 之IDEA 集成使用 GitHub(Git同时管理本地仓库和远程仓库)

2 .IDEA 集成使用 GitHub&#xff08;Git同时管理本地仓库和远程仓库&#xff09; 首先在 IDEA 的设置中绑定 GitHub 的账号 先创建一个 test1.txt 文件&#xff0c;内容为 aaa. 最上一栏 VCS&#xff0c; SHARE ON GitHub&#xff0c;然后选择要发送到远程仓库的文件即可。…...

CSS滚动条样式修改

前言 目前我们可以通过 CSS伪类 来实现滚动条的样式修改&#xff0c;以下为修改滚动条样式用到的CSS伪类&#xff1a; ::-webkit-scrollbar — 整个滚动条 ::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头) ::-webkit-scrollbar-thumb — 滚动条上的滚动滑块 ::-web…...

《零秒思考》像麦肯锡精英一样思考 - 三余书屋 3ysw.net

零秒思考&#xff1a;像麦肯锡精英一样思考 大家好&#xff0c;今天我们要深入探讨的著作是《零秒思考》。在领导提出问题时&#xff0c;我们常常会陷入沉思&#xff0c;却依然难以有所进展&#xff0c;仿佛原地踏步&#xff0c;但是身边的同事却能够立即给出清晰的回答。这种…...

使用docker制作Android镜像(实操可用)

一、安装包准备 1、准备jdk 下载地址&#xff1a;Java Downloads | Oracle 注意版本&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我下载的jdk17&#xff0c;不然后面构建镜像报错&#xff0c;就是版本不对 2、准备安装的工具包 ttps://dev…...

大厂MVP技术JAVA架构师培养

课程介绍 这是一个很强悍的架构师涨薪计划课程&#xff0c;课程由专家级MVP讲师进行教学&#xff0c;分为是一个章节进行分解式面试及讲解&#xff0c;不仅仅是面试&#xff0c;更像是一个专业的架构师研讨会课程。课程内容从数据结构与算法、Spring Framwork、JVM原理、 JUC并…...

uniapp实现文件和图片选择上传功能实现

主要介绍了uni-file-picker文件选择上传,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 上传一张: <template><view class="container example"><uni-forms ref="baseForm" …...

2024认证杯数学建模C题思路模型代码

目录 2024认证杯数学建模C题思路模型代码&#xff1a;4.11开赛后第一时间更新&#xff0c;获取见文末名片 以下为2023年认证杯C题&#xff1a; 2024年认证杯数学建模C题思路模型代码见此 2024认证杯数学建模C题思路模型代码&#xff1a;4.11开赛后第一时间更新&#xff0c;获…...

springcloud项目中,nacos远程的坑

我将允许重写放在了远程nacos的注册中心&#xff0c;还是无法启动。这个bug&#xff0c;想想确实也可以解决。 解决方案 1.配置到bootstrap.yml或者application.yml中 2.实现EnvironmentPostProcessor并设置值&#xff0c;并在META-INF中注入我们的类 org.springframework.boot…...

南京航空航天大学-考研科目-513测试技术综合 高分整理内容资料-01-单片机原理及应用分层教程-单片机有关常识部分

系列文章目录 高分整理内容资料-01-单片机原理及应用分层教程-单片机有关常识部分 文章目录 系列文章目录前言总结 前言 单片机的基础内容繁杂&#xff0c;有很多同学基础不是很好&#xff0c;对一些细节也没有很好的把握。非常推荐大家去学习一下b站上的哈工大 单片机原理及…...

【python】Flask Web框架

文章目录 WSGI(Web服务器网关接口)示例Web应用程序Web框架Flask框架创建项目安装Flask创建一个基本的 Flask 应用程序调试模式路由添加变量构造URLHTTP方法静态文件模板—— Jinja2模板文件(Template File)<...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...