我在C#中使用iText填写pdf表格。有填充单选按钮和文本字段,当我完成后,我希望这些字段不可编辑 - 扁平化。只要我不打电话,一切都很好
form.FlattenFields();
在那些填满文本的字段被打破之后 - 每个字母变成一个矩形。当我不调用form.FlattenFields()这些字段很好,但仍然可以编辑,这不是我想要的。码:
PdfReader reader = new PdfReader(src);
PdfDocument pdf = new PdfDocument(reader, new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
form.GetField("question1").SetValue("Text");
form.FlattenFields();
pdf.Close();
简而言之:PDF中的表单已被破坏,它要求使用字体而字符代码和Unicode代码点之间没有正确的映射。此外,该字体中的所有字形都是空的,因此即使PDF处理器以某种方式获得映射的想法,它仍然只显示空字形。
因此,PDF处理器必须忽略表单的请求,并引入自己的字体来填写表单,因为您希望它被填充。
在您提出的问题中
只要我不打电话,一切都很好
form.FlattenFields();
在那些填满文本的字段被打破之后
实际上,你的未展平的PDF已经破了:
这不是由于观众,该表格字段的外观流看起来像这样:
q
0 0 0 RG
0 0 151 12.36 re
S
Q
/Tx BMC
q
n
q
BT
/F0 12 Tf
4 1.32 Td
0.26667 0.26667 0.26667 rg
<0000000000000000> Tj
ET
Q
Q
EMC
如你所见,显示的字符串是<0000000000000000>
,即四个0000
字形。但是,该字体可能会被编码,这不能代表"Text"
。
此PDF中的"Text"
仅出现一次:作为抽象表单字段的值。因此,如果PDF查看器不采用PDF中给出的外观但是自己创建一个(例如,在编辑表单字段时),它可能会显示代表"Text"
的内容。
已经看到已经没有展平的原始填充被破坏并且想知道可能导致这种情况的原因,让我们看一下表单字段属性。
首先,这是DA(默认外观)属性的值,该属性用于构造上面的外观流:
.266667 .266667 .266667 rg
/F0 12 Tf
您将在上面的外观流中识别两个指令(在前一行中填充颜色定义,在后一行中填充字体和字体大小)。
外观流资源和默认资源(AcroForm条目DR)中的字体名称F0解析为相同的字体:
28 0 obj
<<
/Type/Font
/BaseFont/WRCKAA+TimesNewRomanPSMT
/ToUnicode 29 0 R
/Subtype/Type0
/DescendantFonts[33 0 R]
/Encoding/Identity-H
>>
endobj
编码是Identity-H,这实际上意味着PDF中使用的字符代码与字体中使用的代码相同。因此,没有关于代码实际含义的信息。
但是上面引用了一个ToUnicode地图!我们来看看它的内容:
/CIDInit /ProcSet findresource
begin
12 dict
begin
begincmap
/CIDSystemInfo <</Ordering (UCS) /Registry (Adobe) /Supplement 0 >> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <ffff> endcodespacerange
1 beginbfchar
<0003> <0020> endbfchar
endcmap
CMapName
currentdict
/CMap defineresource
pop
end
end
只有一个映射,字符代码0003
映射到0020
,Unicode代码点为空格,没有别的!
因此,表单定义要求PDF处理器使用特定字体进行填充,但此字体不提供有关此字体中哪些字符代码表示哪个Unicode值的信息。因此,尝试按要求执行的PDF处理器只能填写表单!
此外,该字体的BaseFont值为WRCKAA + TimesNewRomanPSMT。该6字母前缀表示此字体不是完整的TimesNewRomanPSMT,而只是其中的一部分。让我们看一下字体中的字形绘图信息:
等等超过4000个字形。
因此,字体只有第一个字形的非空图形(名为".notdef"
,即它代表未定义的字形),所有其他字形都是空的!
此外,字体包含有关Unicode映射字符代码的自己的信息(否则表中不会有任何字符标题)。 PDF处理器不需要使用这些信息,但如果它使用过它们,它会被愚弄成使用最终只代表空字形的字符代码!