使用iText将pdf格式的字段展平后,用矩形代替字母

时间:2019-04-05 07:25:19

标签: c# pdf itext

我正在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();

1 个答案:

答案 0 :(得分:0)

简而言之:PDF中的表单已损坏,它要求使用字体,而字符代码和Unicode代码点之间没有正确的映射。此外,该字体中的所有字形都是空的,因此即使PDF处理器以某种方式知道映射的想法,它仍将仅显示空字形。

因此,PDF处理器必须忽略表单的请求,并引入自己的字体以按预期填充表单。

分析表单字段未展平的PDF

您提出的问题

  

只要我不打电话,一切都很好

form.FlattenFields();
     

在那之后填充文本的字段被破坏

实际上,实际上,未拼合的PDF已经损坏:

screen shot

这不是由于查看器所致,该表单字段的外观流如下所示:

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 都解析为相同的字体:< / p>

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,即 space 的Unicode代码点!

因此,表单定义要求PDF处理程序使用特定的字体进行填充,但是此字体不提供有关此字体中的哪些字符代码表示哪个Unicode值的信息。因此,PDF处理程序试图按要求执行只能填写表格!

此外,该字体的 BaseFont 值为 WRCKAA + TimesNewRomanPSMT 。该6个字母的前缀表示此字体不是完整的TimesNewRomanPSMT,而只是其一部分。因此,让我们看一下字体中的字形绘图信息:

F0 characters

依此类推,等等,超过4000个字形。

因此,该字体仅对第一个字形(名为".notdef",即表示未定义的字形)具有一个非空的图形,所有其他字形均被绘制为空!

此外,字体包含其自己的有关将字符代码映射到Unicode的信息(否则表中将没有任何字符标题)。 PDF处理器不需要使用这些信息,但是如果使用了这些信息,它将被愚弄为使用字符代码,而这些字符代码最终都只能代表空字形!