【发布时间】:2017-03-15 15:51:26
【问题描述】:
我正在尝试在 iText 中创建一个带有填写表格的多页 PDF 文档,每个人一份。我在互联网上查找了如何执行此操作的示例,并在我的解决方案中使用了这些示例。
PDF 模板是使用 Adobe Acrobat Pro 创建的。
我已经能够使用 iText 从我的模板中成功填写并返回单页 PDF 文档,但多文档流程似乎无法正常工作。
这是我的程序,展示了我正在尝试做的事情:
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfSmartCopy;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
public class ITextTest
{
public static final String TEMPLATE =
"C:\\RAD7_5\\iTextTest\\iTextTest\\input\\LS213_1.pdf";
public static void main(String[] args)
{
ITextTest iTextTest = new ITextTest();
iTextTest.doItextTest();
}
public void doItextTest()
{
try
{
PdfReader pdfReader;
PdfStamper pdfStamper;
ByteArrayOutputStream baos;
Document document = new Document();
PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document,
new FileOutputStream("C:\\RAD7_5\\iTextTest\\iTextTest\\output\\LS213_1MultiTest.pdf"));
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date currDate = new Date();
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
double amount = 4127.29d;
document.open();
for(int i = 1; i <= 5; i++)
{
pdfReader = new PdfReader(TEMPLATE);
baos = new ByteArrayOutputStream();
pdfStamper = new PdfStamper(pdfReader, baos);
AcroFields acroFields = pdfStamper.getAcroFields();
//key statement 1
acroFields.setGenerateAppearances(true);
//acroFields.setExtraMargin(5, 5);
acroFields.setField("Name and Address", "John Doe\n123 Anywhere St.\nAnytown, USA 12345");
acroFields.setField("Case Number", "123456789");
acroFields.setField("Employer", "Employer Co., Inc.\n456 Anyhow ln.\nAnyville, USA 67890");
acroFields.setField("Date", dateFormat.format(currDate));
acroFields.setField("Name", "John Doe");
acroFields.setField("restitution check No", "65432" + i);
acroFields.setField("in the sum of", numberFormat.format(amount));
//key statement 2
pdfStamper.setFormFlattening(false);
pdfStamper.close();
pdfReader.close();
pdfReader = new PdfReader(baos.toByteArray());
pdfSmartCopy.addPage(pdfSmartCopy.getImportedPage(pdfReader, 1));
pdfSmartCopy.freeReader(pdfReader);
pdfReader.close();
}
document.close();
}
catch(DocumentException dex)
{
dex.printStackTrace();
System.exit(1);
}
catch(IOException ex)
{
ex.printStackTrace();
System.exit(1);
}
}
}
在上面的代码中,可以看到影响填充模板结果的两个关键语句:
acroFields.setGenerateAppearances(true);
pdfStamper.setFormFlattening(false);
使用上述两个语句,如果我将第一个设置为 true,第二个设置为 false,它会填充字段,但它们与标签未对齐。此外,在第一个模板副本之后,之后的每个副本由于某种原因都有一些未填写的字段。
如果我将它们都设置为 true:
acroFields.setGenerateAppearances(true);
pdfStamper.setFormFlattening(true);
它设置所有模板副本中的所有字段。这对我来说是迄今为止最成功的结果,但是填充的字段仍然与标签不对齐,并且如果应用程序中的数据错误,将表单展平设置为 true 不再允许用户在之后手动更正字段。
如果我将第一个设置为 false,第二个设置为 true:
acroFields.setGenerateAppearances(false);
pdfStamper.setFormFlattening(true);
所有字段都是空白的(最坏的结果)。
如果我将它们都设置为 false:
acroFields.setGenerateAppearances(false);
pdfStamper.setFormFlattening(false);
然后字段被填充并与标签右对齐。但是由于某种原因,这些字段显示为空白,直到您单击它们。并且在后续页面中删除某些字段的问题就像在真假场景中一样(提到的第一个场景)。
我想知道是否可以在不对齐字段值、不展平字段以及在后续页面上不丢失字段的情况下使其工作。
我知道您可以使用之后调整边距
acroFields.setExtraMargin(extraMarginLeft, extraMarginTop)
但使用
acroFields.setGenerateAppearances(false)
无需调整页边距即可完美处理单个表单,我希望它也适用于多页文档。
另外,使用
acroFields.setGenerateAppearances(true)
当您单击它时,会使文本在文本框中移动并稍微移位。单页文档和多页文档都会发生这种情况。使用 setGenerateAppearances(true) 设置字段时,使用 Adobe Pro 创建的 iText 或 PDF 模板中似乎存在错误。
我目前使用的是 iText 5.5.8。
对于这个问题的任何帮助将不胜感激。感谢您抽出宝贵时间阅读本文。
【问题讨论】: