我在 iText Group 的问题跟踪器中制作了以下票证:
问题是由 iText 将字段项读入 a 的事实引起的HashMap
,因此无法预测它们将以何种顺序展平。这通常不是问题。如果您不展平 PDF,我认为不会出现此问题,因为在这种情况下,外观存储在小部件注释中,并且在重叠字段的情况下由 PDF 查看器决定哪个字段覆盖另一个字段.
但是,如果表单字段重叠,那么您无法预测在展平时哪个字段将覆盖哪个字段。
假设我们使用 aTreeMap
而不是 a HashMap
,这会解决问题吗?不是真的,因为Comparator
我们会使用哪个?有时会定义 Tab 顺序,但并非总是如此。/Fields
如果没有定义,我们是否应该按照它们在数组中出现的顺序对字段进行排序?/Annots
或者根据数组中小部件注释的顺序对它们进行排序是否更有意义?另一种选择是根据它们在页面上的位置对它们进行排序。简而言之:这不是 iText 应该做出的决定。
但是,如果有人想解决这个问题,我们可以Comparator
为PdfStamperImp
. 如果
Comparator
提供了这样的 a(我们甚至可以提供一些实现),那么展平过程将按照Comparator
.
这张票的优先级很低(我假设您不是 iText Software 公司之一的客户),但在写这张票时,我有了另一个想法。
我已经在评论中使用 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
数组中。这些字段按照您想要的确切顺序填写。注释现在涵盖了日期,而不是相反。