iText7,无法在不出现错误的情况下设置 formField 值
iText7, cannot set formField value without getting error
我正在尝试添加一个字段和注释,但是当我尝试设置该值时,出现此错误 object.must.be.indirect.to.work.with.this.wrapper
。似乎无论设置哪个字段或在何处设置都会发生此错误。有谁知道如何解决这个错误?
这是导致我的问题的示例代码:
public class HelloWorld {
public static final String DEST = "sampleOutput.pdf";
public static final String SRC = "sample.pdf";
public static void main(String args[]) throws IOException {
new HelloWorld().createPdf(SRC, DEST);
}
public void createPdf(String src, String dest) throws IOException {
//Initialize PDF reader and writer
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
//Initialize PDF document
PdfDocument pdf = new PdfDocument(reader, writer);
// Initialize document
Document document = new Document(pdf);
HelloWorld.addAcroForm(pdf, document);
//Close document
document.close();
}
public static PdfAcroForm addAcroForm(PdfDocument pdf, Document doc) throws IOException {
int numPages = pdf.getNumberOfPages();
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfTextFormField confField = PdfFormField.createText(pdf);
confField.setFieldName("confirmation");
PdfSignatureFormField sigField = PdfFormField.createSignature(pdf);
sigField.setFieldName("signature");
PdfWidgetAnnotation firstPageConf = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
PdfWidgetAnnotation pageConf = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
PdfWidgetAnnotation signature = new PdfWidgetAnnotation(new Rectangle(0, 100, 425, 15));
//add conf annotation based on first page or not
for (int i = 1; i <= numPages; i++) {
PdfPage page = pdf.getPage(i);
if (i == 1) {
page.addAnnotation(firstPageConf);
} else {
page.addAnnotation(pageConf);
}
}
form.addField(confField);
form.addField(sigField);
confField.addKid(firstPageConf);
confField.addKid(pageConf);
sigField.addKid(signature);
//this one is different because we try to set a value....
PdfTextFormField testField = PdfFormField.createText(pdf);
testField.setFieldName("test");
PdfWidgetAnnotation test = new PdfWidgetAnnotation(new Rectangle(0, 100, 425, 15));
pdf.getPage(1).addAnnotation(test);
testField.addKid(test);
testField.setValue("testValue");//error 'object.must.be.indirect.to.work.with.this.wrapper' occurs here
return form;
}
}
首先:我们注意到当前 iText 7 版本中的错误消息存在问题。您看到的错误是错误的 key,而不是错误消息的 value。幸运的是,错误消息的关键已经给了我们足够的信息来知道哪里出了问题。
在 PDF 中有直接宾语和间接宾语。直接对象是未引用的对象本身。在这种情况下,您有一个注释字典,它是一个直接对象(test
对象)。
您小时候试图将其添加到字段中,错误告诉您:嘿,我无法处理直接对象。我需要对间接对象的间接引用。您正在添加一个尚不被称为间接对象的对象,因此我无法添加它。
如何解决这个问题?那么,您应该确保将 test
作为间接宾语添加到文档中。一种方法是将它作为注释添加到页面中(这是你 应该 做的,否则你的代码没有任何意义)。
所以让我们添加一行:
PdfTextFormField testField = PdfFormField.createText(pdf);
testField.setFieldName("test");
PdfWidgetAnnotation test = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
pdf.getPage(1).addAnnotation(test);
testField.addKid(test);
testField.setValue("testValue");
通过添加行:
pdf.getPage(1).addAnnotation(test);
我们将注释词典作为间接对象添加到 PDF 中。创建了一个参考。当您使用 addKid()
方法时会使用该引用。
@Bruno 的 几乎做到了。但在手头的情况下,不仅注释 test
,而且表单字段 testField
都需要在设置字段值之前进行间接处理。幸运的是,这可以作为将字段添加到 AcroForm 的副作用来实现,无论如何你都应该这样做。
因此,只需添加行
form.addField(testField);
就在 testField.setValue
调用之前,参见。测试 AddFieldWithValue.java,特别是方法 testAddLineElliot
和 addAcroForm
.
我正在尝试添加一个字段和注释,但是当我尝试设置该值时,出现此错误 object.must.be.indirect.to.work.with.this.wrapper
。似乎无论设置哪个字段或在何处设置都会发生此错误。有谁知道如何解决这个错误?
这是导致我的问题的示例代码:
public class HelloWorld {
public static final String DEST = "sampleOutput.pdf";
public static final String SRC = "sample.pdf";
public static void main(String args[]) throws IOException {
new HelloWorld().createPdf(SRC, DEST);
}
public void createPdf(String src, String dest) throws IOException {
//Initialize PDF reader and writer
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
//Initialize PDF document
PdfDocument pdf = new PdfDocument(reader, writer);
// Initialize document
Document document = new Document(pdf);
HelloWorld.addAcroForm(pdf, document);
//Close document
document.close();
}
public static PdfAcroForm addAcroForm(PdfDocument pdf, Document doc) throws IOException {
int numPages = pdf.getNumberOfPages();
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfTextFormField confField = PdfFormField.createText(pdf);
confField.setFieldName("confirmation");
PdfSignatureFormField sigField = PdfFormField.createSignature(pdf);
sigField.setFieldName("signature");
PdfWidgetAnnotation firstPageConf = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
PdfWidgetAnnotation pageConf = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
PdfWidgetAnnotation signature = new PdfWidgetAnnotation(new Rectangle(0, 100, 425, 15));
//add conf annotation based on first page or not
for (int i = 1; i <= numPages; i++) {
PdfPage page = pdf.getPage(i);
if (i == 1) {
page.addAnnotation(firstPageConf);
} else {
page.addAnnotation(pageConf);
}
}
form.addField(confField);
form.addField(sigField);
confField.addKid(firstPageConf);
confField.addKid(pageConf);
sigField.addKid(signature);
//this one is different because we try to set a value....
PdfTextFormField testField = PdfFormField.createText(pdf);
testField.setFieldName("test");
PdfWidgetAnnotation test = new PdfWidgetAnnotation(new Rectangle(0, 100, 425, 15));
pdf.getPage(1).addAnnotation(test);
testField.addKid(test);
testField.setValue("testValue");//error 'object.must.be.indirect.to.work.with.this.wrapper' occurs here
return form;
}
}
首先:我们注意到当前 iText 7 版本中的错误消息存在问题。您看到的错误是错误的 key,而不是错误消息的 value。幸运的是,错误消息的关键已经给了我们足够的信息来知道哪里出了问题。
在 PDF 中有直接宾语和间接宾语。直接对象是未引用的对象本身。在这种情况下,您有一个注释字典,它是一个直接对象(test
对象)。
您小时候试图将其添加到字段中,错误告诉您:嘿,我无法处理直接对象。我需要对间接对象的间接引用。您正在添加一个尚不被称为间接对象的对象,因此我无法添加它。
如何解决这个问题?那么,您应该确保将 test
作为间接宾语添加到文档中。一种方法是将它作为注释添加到页面中(这是你 应该 做的,否则你的代码没有任何意义)。
所以让我们添加一行:
PdfTextFormField testField = PdfFormField.createText(pdf);
testField.setFieldName("test");
PdfWidgetAnnotation test = new PdfWidgetAnnotation(new Rectangle(0, 0, 425, 15));
pdf.getPage(1).addAnnotation(test);
testField.addKid(test);
testField.setValue("testValue");
通过添加行:
pdf.getPage(1).addAnnotation(test);
我们将注释词典作为间接对象添加到 PDF 中。创建了一个参考。当您使用 addKid()
方法时会使用该引用。
@Bruno 的 test
,而且表单字段 testField
都需要在设置字段值之前进行间接处理。幸运的是,这可以作为将字段添加到 AcroForm 的副作用来实现,无论如何你都应该这样做。
因此,只需添加行
form.addField(testField);
就在 testField.setValue
调用之前,参见。测试 AddFieldWithValue.java,特别是方法 testAddLineElliot
和 addAcroForm
.