所以我想检查 itext(版本 8)是否适合我的需要
我需要添加符号字段并基于它们以宏形式锁定一些其他字段,
所以我喜欢它:
PdfWriter writer = new PdfWriter("AddSignFieldItext77.pdf");
iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(writer);
var newPage = pdf.AddNewPage(new PageSize(PageSize.A4));
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
var formRectangle = new iText.Kernel.Geom.Rectangle(100, 800, 200, 20);
var formFieldBuilder = new TextFormFieldBuilder(pdf, "TextFormField1");
formFieldBuilder.SetPage(newPage);
formFieldBuilder.SetWidgetRectangle(formRectangle);
var formfield = formFieldBuilder.CreateText();
form.AddField(formfield);
var formRectangle2 = new iText.Kernel.Geom.Rectangle(100, 700, 200, 20);
var formFieldBuilder2 = new TextFormFieldBuilder(pdf, "TextFormField2");
formFieldBuilder2.SetPage(newPage);
formFieldBuilder2.SetWidgetRectangle(formRectangle2);
var formfield2 = formFieldBuilder2.CreateText();
form.AddField(formfield2);
var signatureRectangle1 = new iText.Kernel.Geom.Rectangle(36, 448, 200, 100);
var signatureField1 = new SignatureFormFieldBuilder(pdf, "SignField1");
signatureField1.SetPage(newPage);
signatureField1.SetWidgetRectangle(signatureRectangle1);
PdfSignatureFormField sig1 = signatureField1.CreateSignature();
PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();
string[] fieldToLock1 = new string[] { "TextFormField1" };
pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);
PdfDictionary dict = sig1.GetPdfObject();
dict.Put(PdfName.Lock,pdfSigFieldLock1.GetPdfObject());
form.AddField(sig1);
var signatureRectangle2 = new iText.Kernel.Geom.Rectangle(36, 248, 200, 100);
var signatureField2 = new SignatureFormFieldBuilder(pdf, "SignField2");
signatureField2.SetPage(newPage);
signatureField2.SetWidgetRectangle(signatureRectangle2);
PdfSignatureFormField sig2 = signatureField2.CreateSignature();
PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();
string[] fieldToLock2 = new string[] { "TextFormField2", };
pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE,fieldToLock2 );
PdfDictionary dict2 = sig2.GetPdfObject();
dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
form.AddField(sig2);
pdf.Close();
这几乎可以正常工作-像这样生成 pdf
我可以签署第一场。没事。已保存,已签名,
TextFormField1
已锁定。
然后如果我想在第二个字段上签名——我得到错误,如屏幕截图所示,函数参数值不正确?
如果我关闭并重新打开文档-我可以在这个
SignField2
上无误地登录
但我不想为了第二次签名而关闭并重新打开文档
请建议如何解决这个问题——我在这里遗漏了什么吗?有更好的方法吗?
致以诚挚的问候
事实上,当您尝试在单个会话中对两个签名字段进行签名时,Adobe Acrobat(至少是我目前使用的版本 2023.001.20174)会遇到问题。
第一次检查时,PDF 中没有发现任何错误。因此,我使用 Adobe Acrobat 本身创建了一个类似的文件,并观察到 Adobe Acrobat 没有遇到同样的问题。然后我确定了差异并试图找出哪些差异是相关的。
事实证明,只有一个相关的区别:如果签名字段词典具有正确的 Type 条目,Adobe Acrobat 可以在单个会话中对两个 PDF 签名字段进行签名。另一方面,iText 默认不添加 Type 条目。
由于 Type 条目被指定为 optional 并且在签名字段字典的情况下只有一个允许的值,这显然可以被认为是 Adobe Acrobat 错误。
作为变通方法,您可以像这样使用 iText 显式添加类型:
...
PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();
string[] fieldToLock1 = new string[] { "TextFormField1" };
pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);
PdfDictionary dict = sig1.GetPdfObject();
dict.Put(PdfName.Type, PdfName.Annot); // <-----
dict.Put(PdfName.Lock, pdfSigFieldLock1.GetPdfObject());
form.AddField(sig1);
...
PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();
string[] fieldToLock2 = new string[] { "TextFormField2", };
pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock2);
PdfDictionary dict2 = sig2.GetPdfObject();
dict2.Put(PdfName.Type, PdfName.Annot); // <-----
dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
form.AddField(sig2);
...