iTextSharp复选框具有值,但未显示为已选中

Y.Y*_*.Y. 0 c# pdf checkbox itext

我需要使用iTextSharp编辑PDF文件。我有一个单选按钮和复选框,如下所述。

我想要以下内容:如果我在单选按钮上打了一个勾号,则该复选框必须显示为选中状态。

在代码中,单选按钮具有一个值,但是当我第一次打开PDF文件时,未选中该复选框。

当我再次在单选按钮中放置一个复选标记时,它变为可见。

这是我的代码;

PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.OpenOrCreate)); 
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("4a.0", "1"); // radio button
pdfFormFields.SetField("4a.1", "1"); // checkbox
pdfFormFields.SetField("4a.2", "2010"); // text box 
Run Code Online (Sandbox Code Playgroud)

mkl*_*mkl 6

OP的代码中既存在引起与PDF无关的问题的问题,又存在导致PDF特定的问题的PDF的特殊属性。

PDF独立问题

关闭 PdfStamper

OP提供的代码不会关闭PdfStamper。但是,这是必需的,如果不关闭压模,将不会写入重要信息:

...
pdfStamper.Close();
Run Code Online (Sandbox Code Playgroud)

不过,我认为OP确实关闭了压模,但只是忘记将这一行复制到他的问题中,因为我在不关闭压模的情况下观察到的错误是不同的。

不当 FileMode

OP用于new FileStream(newFile, FileMode.OpenOrCreate)创建文件输出流。文件模式OpenOrCreate记录为:

// Summary:
//     Specifies that the operating system should open a file if it exists; otherwise,
//     a new file should be created. If the file is opened with FileAccess.Read,
//     System.Security.Permissions.FileIOPermissionAccess.Read permission is required.
//     If the file access is FileAccess.Write, System.Security.Permissions.FileIOPermissionAccess.Write
//     permission is required. If the file is opened with FileAccess.ReadWrite,
//     both System.Security.Permissions.FileIOPermissionAccess.Read and System.Security.Permissions.FileIOPermissionAccess.Write
//     permissions are required.
OpenOrCreate = 4,
Run Code Online (Sandbox Code Playgroud)

因此,如果newFile已经存在,则压模将写入该文件,并且如果压模创建的文件比以前的现有文件短,则该先前内容的末尾将保留下来并有效地使PDF无效。

因此,请改用FileMode.Create记录为:

// Summary:
//     Specifies that the operating system should create a new file. If the file
//     already exists, it will be overwritten. This requires System.Security.Permissions.FileIOPermissionAccess.Write
//     permission. FileMode.Create is equivalent to requesting that if the file
//     does not exist, use System.IO.FileMode.CreateNew; otherwise, use System.IO.FileMode.Truncate.
//     If the file already exists but is a hidden file, an System.UnauthorizedAccessException
//     exception is thrown.
Create = 2,
Run Code Online (Sandbox Code Playgroud)

追加模式

OP的代码在追加模式下不使用压模。对于以前签名的文档,这会导致签名中断。对于共享的OP,确实有一个签名,即所谓的使用权签名。因此,当再次打开PDF时,Adobe Reader显示:

扩展功能丢失

因此,请使用附加模式(或完全放弃使用权签名):

PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create), '\0', true);
Run Code Online (Sandbox Code Playgroud)

PDF相关问题

PDF不完全符合PDF规范

正如对该问题的评论中所述:

表格有些滥用PDF。两者4a.04a.1是具有没有按钮字段FF(字段标志)入口,即对于这两个字段的标志值是默认0,这意味着这两个按钮字段是复选框字段既不是按钮也不无线电标志被设置。但是,通过让多个孩子(除“ 关”外)不知道共同的外观状态,它们的行为就像单选按钮。PDF功能的这种使用是互操作性的障碍。

但是iText对此没有任何问题。不过,PDF应该是固定的。

隐藏的值

这是有问题的PDF部分:

Gegevens garantieverklaring已标记

在执行OP的代码时,您会看到4a.0标记了top元素,但是在子字段4a.1或中没有任何区别4a.2

这样做的原因是,虽然顶级元素(单选按钮4a.0)始终是可见的,依赖的元素4a.14a.24a.3(以及同样也依赖于其他顶级单选按钮,选择的元素)在OP的文件作为标记隐藏,因此不会显示其值。

在PDF查看器中,选中相关顶级菜单单选按钮时,相关字段的隐藏标志会通过JavaScript操作重置。因此,相关字段值变得可见。

另一方面,iTextSharp不包含执行此类操作的JavaScript引擎。因此,那些字段保持隐藏。

因此,不仅请设置字段值,还请重置关联的隐藏标志:

pdfFormFields.SetField("4a.1", "1"); // checkbox
pdfFormFields.SetFieldProperty("4a.1", "clrflags", 2, null);
pdfFormFields.SetField("4a.2", "2010"); // text box 
pdfFormFields.SetFieldProperty("4a.2", "clrflags", 2, null);
Run Code Online (Sandbox Code Playgroud)

应用所有更改

所有更改的来源是这样的:

PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create), '\0', true);
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("4a.0", "1"); // radio button
pdfFormFields.SetField("4a.1", "1"); // checkbox
pdfFormFields.SetFieldProperty("4a.1", "clrflags", 2, null);
pdfFormFields.SetField("4a.2", "2010"); // text box 
pdfFormFields.SetFieldProperty("4a.2", "clrflags", 2, null);
pdfStamper.Close();
Run Code Online (Sandbox Code Playgroud)

结果看起来像这样:

Gegevens garantieverklaring填充