iTextSharp插入图像按钮字段不工作
我找了又找,找不到我问题的答案。我在我的代码中尝试了许多不同的方法,但我遇到了困难,我不知道从这里可以走到哪里。我似乎想做与这两条线相同的事情: 他们非常相似,答案是一样的。然而,当我使用这个精确的代码时,结果是一个没有图像的PDF。这是我的密码:iTextSharp插入图像按钮字段不工作,itext,Itext,我找了又找,找不到我问题的答案。我在我的代码中尝试了许多不同的方法,但我遇到了困难,我不知道从这里可以走到哪里。我似乎想做与这两条线相同的事情: 他们非常相似,答案是一样的。然而,当我使用这个精确的代码时,结果是一个没有图像的PDF。这是我的密码: using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open)) using (var newFileStream = new FileStrea
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(@"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
我试图排除所有显而易见的事情。我的图像路径是正确的,当我读取现有PDF字段并获取字段类型时,该字段实际上是一个按钮字段。如果我在Adobe Reader中打开PDF并单击图像的占位符,它允许我从电脑中选择一个文件。当我将图像放入文件中,保存,然后读取该PDF时,我可以将代码更改为:
imageField.ProportionalIcon = false;
现在,图像突然在保存的副本上拉伸。所以我看到它正在改变这一部分,但这是当我在AdobeReader中手动输入图像时。当我在AdobeReader中设置图像并正确显示后在字段中阅读时,我看到了一些有趣的事情。field.Image属性为NULL,field.IconReference不为NULL。当我使用原始代码尝试插入图像时,它是反向的,其中图像不是NULL,但IconReference是NULL
任何帮助都将不胜感激,谢谢
编辑1:好的,我第一次没有看到它,但我回去更彻底地检查了一下,我确实找到了那把钥匙。这是:
这里有几件事在起作用 使用权: PDF使用Adobe拥有的私钥进行数字签名 您可以在此处使用RUP看到这一点(在屏幕截图中,您没有深入到足够的深度): 这有两个含义:
- 签名解锁Adobe Reader中的特殊权限,例如在本地保存已填写表单的权限
- 对原始PDF进行任何更改都会破坏签名并删除导致Adobe Reader中出现错误消息的特殊权限
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
这是iText 5代码:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
这是iText 5的答案
混合形式:
如果单击/AcroForm
条目,您会看到:
有一个/Fields
数组,其中引用的字段字典也是小部件注释。这意味着文档内部有一个AcroForm。但是,还有一个包含一系列XML片段的/XFA
条目。这意味着文档中有一个XFA表单
换句话说:相同的表单描述在内部添加了两次。在一个表单(AcroForm部分)中更改按钮,但在另一个表单(XFA表单)中不更改按钮,这会导致不一致
XFA在PDF 2.0中已被弃用,因为支持该技术的供应商不多。面对使用不推荐的技术的表单是一件令人沮丧的事情
我的建议:我将删除XFA部件。请参阅常见问题解答条目“删除XFA安全吗?”/
在iText 5中,删除XFA的操作如下:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
重要提示:我的建议是从PDF中删除所有不推荐的功能,但如果政府希望该功能出现,那么你就倒霉了。在这种情况下,您需要使用Adobe软件来处理表单。如果是这样,你可以向政府抱怨,他们的要求导致了事实上的供应商锁定。顺便说一下:iText软件也是一家供应商。这是一家开源公司,根据AGPL许可证提供开源软件。AGPL许可证允许在某些情况下免费使用(请参阅)。如果您不满足这些要求,您必须购买商业许可证才能使用iText。您确定您的表单是AcroForm吗?查看字段的名称(
form1[0].ec_Bldg_Photo_1[0].ImageField2[0]
),我发誓这是一个XFA表单。如果它是XFA表单,您不应该期望AcroForm代码工作。XFA在PDF 2.0(即ISO-32000-2)中已被弃用,因为所有人都撞到了您刚刚撞到的墙。弃用意味着不再支持它。如果仍然需要解决此问题,您可能希望获得iText支持。顺便说一句,你也在使用一个过时的iText版本,自愿支持已经停止。哇,谢谢你,布鲁诺,很抱歉我对PDF开发有点陌生,所以我不确定它是否是XFA。我有一个客户寄给我,希望我自动填写。有没有简单的检查方法?如果是XFA,获取其AcroForm版本的最佳方法是什么?是否可以使用Acrobat的专业版进行转换?最后,我认为我使用的是最新的支持iTextSharp for C#的iText。也许我误解了这个网站。我猜如果我不更新到版本7,我可能会遇到麻烦?非常感谢。我以为我使用的是最新的iText,它支持C#的iTextSharp。官方网站并不是这么说的:至于检查一个文件是纯XFA文件、混合XFA文件还是纯AcroForm文件,最好的方法是用(给我们一个屏幕截图,显示一下/AcroForm
键下的内容)查看PDF文件。哦,好的,是的,我明白我的困惑所在。我认为我必须使用iTextSharp,它最多有5个,但iText是它的新名称:)我认为iText是不同的,显然很困惑!好的,非常感谢你,布鲁诺,我来看看