我有一个pdf与文本表单字段是分层的,一个在另一个之上。当我通过iText填充字段并将表单扁平化时,我在其他表单字段顶部创建的表单字段现在位于底部。
例如,我有一个名为"number_field“的文本字段,它位于名为"name_field”的第二个文本字段下面。当我通过iText为这些字段设置值( number_field为SO10,name_field为'John‘)时,number_field现在位于name_field之上。
如何用iText更改这些字段页面上的顺序?有可能吗?
链接到示例PDF:https://freecompany.sharefile.com/d-s84f6d63e7d04fe79
发布于 2015-04-16 15:01:29
我已在iText集团的发行追踪器中取得以下票:
一个问题是由iText将字段项读取到
HashMap中引起的,因此无法预测它们将按什么顺序被扁平。这通常不是问题。我不认为这个问题发生在如果您不扁平PDF的情况下,因为在这种情况下,外观存储在小部件注释中,在发生重叠字段的情况下,由PDF查看器来决定哪个字段覆盖另一个字段。 但是,如果表单字段重叠,则无法预测哪个字段在扁平时覆盖哪个字段。 假设我们使用的是TreeMap而不是HashMap,这能解决问题吗?不太可能,因为我们会使用哪个Comparator?有时标签顺序是定义的,但并不总是这样.如果没有定义字段,我们是否应该按照字段在/Fields数组中出现的顺序排序呢?或者,根据/Annots数组中的小部件注释的顺序对它们进行排序更有意义吗?另一种选择是根据其在页面上的位置对它们进行排序。简而言之:这不是iText应该做出的决定。 但是,如果有人想解决这个问题,我们可以为Comparator创建一个PdfStamperImp成员变量。如果提供了这样一个Comparator(我们甚至可以提供一些实现),那么将按照Comparator定义的顺序执行扁平化过程。
这张票的优先级很低(我假设你不是iText软件公司的客户),但在写这张罚单时,我有了另一个想法。
我已经在评论中提到了使用iTextSharp对文本中的部分下划线。在本例中,您将获得所有字段位置(使用getFieldPositions()方法),并使用ColumnText按正确顺序绘制所有内容。这种方法有几个缺点:为了使字体、字体大小、字体颜色正确,您必须检查字段。这需要一些编程。
我现在张贴这个作为一个答案,因为我有一个更好的选择:填写两张通行证的表格!在FillFormFieldOrder示例中显示了这一点。我们填写表单src,得到如下所示的扁平表单dest:
public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
go2(go1(src), dest);
}如您所见,我们首先执行go1()方法:
public byte[] go1(String src) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
AcroFields form = stamper.getAcroFields();
form.setField("sunday_1", "1");
form.setField("sunday_2", "2");
form.setField("sunday_3", "3");
form.setField("sunday_4", "4");
form.setField("sunday_5", "5");
form.setField("sunday_6", "6");
stamper.setFormFlattening(true);
stamper.partialFormFlattening("sunday_1");
stamper.partialFormFlattening("sunday_2");
stamper.partialFormFlattening("sunday_3");
stamper.partialFormFlattening("sunday_4");
stamper.partialFormFlattening("sunday_5");
stamper.partialFormFlattening("sunday_6");
stamper.close();
reader.close();
return baos.toByteArray();
}这将填充所有sunday_x字段,并使用部分表单扁平化只对这些字段进行平放。go1()方法以src作为参数,并返回一个byte[]将部分扁平形式。
byte[]将用作go2()方法的参数,该方法将dest作为其第二个参数。现在,我们将填写sunday_x_notes字段:
public void go2(byte[] src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
form.setField("sunday_1_notes", "It's Sunday today, let's go to the sea");
form.setField("sunday_2_notes", "It's Sunday today, let's go to the park");
form.setField("sunday_3_notes", "It's Sunday today, let's go to the beach");
form.setField("sunday_4_notes", "It's Sunday today, let's go to the woods");
form.setField("sunday_5_notes", "It's Sunday today, let's go to the lake");
form.setField("sunday_6_notes", "It's Sunday today, let's go to the river");
stamper.setFormFlattening(true);
stamper.close();
reader.close();
}如你所见,我们现在把所有的田地都夷为平地。结果看起来像这

现在,您不必再担心字段的顺序,不需要担心/Fields数组中的字段顺序,也不必担心/Annots数组中字段的顺序。这些字段按照您想要的顺序填写。笔记现在包括日期,而不是相反的方式。
https://stackoverflow.com/questions/29633035
复制相似问题