iTextSharp复选框具有值,但在选中时不可见

时间:2017-02-07 14:06:48

标签: 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 

1 个答案:

答案 0 :(得分:6)

OP的代码中存在两个问题,导致独立于PDF的问题,以及导致PDF特定问题的PDF的特殊属性。

PDF独立问题

关闭PdfStamper

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

...
pdfStamper.Close();

我认为,虽然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,

因此,如果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,

追加模式

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

extended features lost

所以请使用追加模式(或完全丢弃使用权签名):

PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create), '\0', true);

PDF相关问题

PDF不完全遵循PDF规范

正如在对该问题的评论中已经提到的那样:

  

表单有点滥用PDF。 4a.04a.1都是没有 Ff (字段标志)条目的按钮字段,即对于这两个字段,flags值是默认值0,这意味着两个按钮字段是复选框字段,因为既没有设置按钮也没有设置Radio标志。但两者都表现得像单选按钮一样,除了关闭之外,还有多个孩子不知道常见的外观状态。 PDF功能的这种使用是互操作性的障碍。

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

隐藏值

这是有问题的PDF部分:

Gegevens garantieverklaring marked

执行OP的代码时,会发现4a.0的顶部元素已被标记,但在子字段4a.14a.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);

已应用所有更改

包含所有更改的来源是:

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();

,结果如下:

Gegevens garantieverklaring filled in