我正在研究一些使用iTextSharp连接PDF文件的代码。我遇到问题a particular PDF包含一些只读字段和一个可编辑的字段(我相信它们是AcroFields)。在输出文件中,所有字段都是可编辑的。
这是我使用的代码(我简化它只读取一个PDF):
public static void Concat(string outputFilePath, string inputFilePath)
{
using (var document = new Document())
{
using (var fileStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite))
using (var copier = new PdfCopy(document, fileStream))
{
copier.SetMergeFields();
document.Open();
var reader = new PdfReader(inputFilePath);
copier.AddDocument(reader);
copier.AddJavaScript(reader.JavaScript);
copier.Close();
}
document.Close();
}
}
有关如何保留字段属性的任何想法?
答案 0 :(得分:3)
看起来iText和Adobe Reader对表单字段结构的解释不同。例如。用一个孩子看这个父字段:
(对象24引自 AcroForm 字典字段数组。对象130引自页字典 ANNOTS 数组。)
因此我们有两个名为PageDataCollection1[0].txtCity
的字段对象,对象24和130,小部件注释合并到后者中。
iText 使用 Ff 值0
认为终端字段对象(对象130)完全负责,其中包括不是只读的。
Adobe Reader 认为终端字段对象(对象130)仅部分负责,使用其 DA 值,但不是其 Ff 值。而是使用父 Ff 值1
,其中包括只读。
在复制文档页面的过程中,层次结构被展平,使得不同的解释可见。
Ad hoc我会说iText的行为在这里是正确的。
Adobe Reader的行为可能来自规范ISO 32000-1:
中的这一部分如果不同的字段字典是具有该名称的共同祖先的后代并且没有自己的部分字段名称( T 条目),则它们可能具有相同的完全限定字段名称。这种字段词典是同一基础字段的不同表示;它们应仅在指定其视觉外观的属性上有所不同。特别是,具有相同完全限定字段名称的字段词典应具有相同的字段类型( FT ),值( V )和默认值( DV < /强>)。
(第12.7.3.2节字段名称)
也许Adobe Reader试图通过忽略没有部分字段名称的后代字段中的其他属性来强制执行同一字段的不同表示仅在指定其可视外观的属性中有所不同。
由于该领域没有不同的表述,因此这里不需要这个措施。
这里有对象结构的另一种解释,@ rhens提议
没有两个名称相同的字段:object 24是字段字典,object 130是widget注释。
IMO这种解释与PDF规范不符,即使它可以解释Adobe Reader的行为。
虽然表单字段的 Kids 数组确实可能包含子字段或小部件,但我认为对象130必须被视为一个字段(其中包含自己的小部件合并到自身)而不是字段对象24的小部件。
要检查某个孩子字典对象是子字段还是仅仅是窗口小部件,它不足以在孩子中找到特定于窗口小部件的条目:这样的条目也可以在子字段中将其单个窗口小部件合并到自身中。因此,必须检查孩子中的特定于字段的条目。
在手边的情况下,kid对象130 具有特定于字段的条目(最重要的是字段类型 FT ,但字段标记 Ff )因此,应该被视为儿童字段。
所有人都说,确实有可能 Adobe确实认为该对象仅仅是一个小部件(如上所述,它将解释行为)。然而,如上所述,这种解释不会受到规范的启发。但它可能受到来自野外的不可忽略数量的文件的启发,这些文档在其简单小部件中错误地具有其他特定于字段的条目,并且要求此解释按设计显示。