我正在使用Itext 5 Maven,我想在多个pdf页面中添加多个文本字段。例如第1页需要3个字段,第2页需要4个字段,等等。
我写了以下代码
public byte[] setupDocument(EditPdfDTO editPdfDTOList, MultipartFile attachment)
{
WritePDF obj = new WritePDF();
Document document = null;
PdfWriter writer = null;
PdfImportedPage page = null;
PdfReader reader = null;
try
{
// Create output PDF
document = new Document(PageSize.A4);
document.setMargins(0, 0, 0, 0);
writer = PdfWriter.getInstance(document,
new FileOutputStream("D:/test.pdf"));
document.open();
PdfContentByte cb = writer.getDirectContent();
// Load existing PDF
reader = new PdfReader(attachment.getBytes());
int totalPages = reader.getNumberOfPages();
for (int i = 0; i < totalPages; i++)
{
page = writer.getImportedPage(reader, i + 1);
document.newPage();
cb.addTemplate(page, 0, 0);
for (int j = 0; j < editPdfDTOList.getPdf().size(); j++)
{
if (i + 1 == editPdfDTOList.getPdf().get(j).getPageNo())
{
BaseFont baseFont = null;
try
{
baseFont = BaseFont.createFont();
}
catch (DocumentException | IOException e1)
{
e1.printStackTrace();
}
int a, b;
a = editPdfDTOList.getPdf().get(j).getxCoordinate();
b = editPdfDTOList.getPdf().get(j).getyCoordinate();
String str = editPdfDTOList.getPdf().get(j).getTextContent();
Rectangle linkLocation =
new Rectangle(a, b + baseFont.getDescentPoint(str, 10),
a + 10 + baseFont.getWidthPoint(str, 10),
b + baseFont.getAscentPoint(str, 10) + 10);
TextField field =
new TextField(writer, linkLocation, "user1" + j+UUID.randomUUID());
field.setFontSize(10);
field.setOptions(TextField.MULTILINE | TextField.READ_ONLY);
field.setTextColor(BaseColor.RED);
field.setText(str);
field.setBorderWidth(1);
cb = writer.getDirectContent();
try
{
cb.addAnnotation(field.getTextField(),false);
}
catch (IOException | DocumentException e)
{
e.printStackTrace();
}
}
}
}
}
catch (DocumentException | IOException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
document.close();
}
return null;
}
此代码只能在每个预期的对象上添加一个Textfield,但不能在单个页面中添加2个或多个Textfield。
没有多个try-catch块的问题。
答案 0 :(得分:3)
首先,您说“要在多个pdf页面中添加多个文本字段” 。当执行这样的任务时,即仅使用一个文档并想要以某种方式操纵它,同时又在结构上保持或多或少保持不变的任务时,通常应该一对PdfReader
/ PdfStamper
一起工作。这使您可以专注于操作,并提供原始PDF及其所有属性的副本。
在单个现有页面上添加多个字段很简单,例如:
PdfReader pdfReader = new PdfReader(resource);
PdfStamper pdfStamper = new PdfStamper(pdfReader, output);
TextField field1 = new TextField(pdfStamper.getWriter(),
new Rectangle(100, 800, 200, 820), "Field1");
field1.setBorderColor(BaseColor.CYAN);
field1.setBorderStyle(PdfBorderDictionary.STYLE_DASHED);
field1.setBorderWidth(BaseField.BORDER_WIDTH_MEDIUM);
field1.setText("Field 1");
pdfStamper.addAnnotation(field1.getTextField(), 1);
TextField field2 = new TextField(pdfStamper.getWriter(),
new Rectangle(300, 800, 400, 820), "Field2");
field2.setBorderColor(BaseColor.RED);
field2.setBorderStyle(PdfBorderDictionary.STYLE_INSET);
field2.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
field2.setText("Field 2");
pdfStamper.addAnnotation(field2.getTextField(), 1);
pdfStamper.close();
(AddField测试testAddMultipleFields
)
应用于我的示例文档
代码生成
因此,将多个文本字段添加到同一文档页面没有任何概念上的问题,它的工作方式非常自然。
在您的情况下,我将改用PdfReader
/ PdfStamper
对。如果仍然存在问题,我将检查您的数据。大概它们每页仅包含一个字段数据集。或两个文本字段具有相同的坐标,因此看起来像一个。或某些文本字段具有屏幕外坐标。或者...或者...或者...
最初,问题中的代码看起来有所不同。最初的答案集中在该代码的问题上。
您声明了密码
只能在每个预期的字段上添加一个文本框,但不能在单个页面中添加2个或多个文本框。
我怀疑是因为
您有两个不同的对象同时"D:/TemplateFilePDf/" + attachment.getOriginalFilename()
和PdfWriter writer
同时写入同一文件PdfStamper stamper
。如果您因代码而得到了一些明智的选择,那么只能靠运气了。和
stamper
的{{1}}实例实例化了{li> null
。实际上,这将在构造函数中导致PdfReader
,这将使您添加文本的文本域根本无法执行。
因此,您共享的代码与您运行的代码有很大的不同,或者您的测试运行实际上都抛出了NullPointerException
,您可能会发现以前的,破坏程度较小的代码的输出仅添加了一个文本字段。
在解决了这两个问题之后,仍然存在一些问题(例如,NullPointerException
的意图是什么?仅在路径定义之后才允许使用该指令,该路径的内部区域要填充,但是我不愿意)看不到您定义任何路径。
此外,您访问cb.fill()
可获得许多相关值,但我们不知道这些值。因此,我们无法运行您的代码来尝试重现该问题。可能您仅创建了一个文本字段,因为该对象仅包含单个文本字段的值...