在使用PDFBOX生成的PDF中,“保存的文本字段”值无法正确显示

import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;

import org.apache.pdfbox.cos.COSDictionary;

import org.apache.pdfbox.cos.COSFloat;

import org.apache.pdfbox.cos.COSName;

import org.apache.pdfbox.cos.COSString;

import org.apache.pdfbox.exceptions.COSVisitorException;

import org.apache.pdfbox.pdmodel.PDDocument;

import org.apache.pdfbox.pdmodel.PDPage;

import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;

import org.apache.pdfbox.pdmodel.interactive.action.type.PDActionJavaScript;

import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;

import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;

import org.junit.Test;

public class TestPDTextbox {

@Test

public void Sample1 () throws IOException, COSVisitorException, BadLocationException {

PDDocument doc = new PDDocument();

PDPage page = new PDPage();

doc.addPage(page);

COSDictionary acroFormDict = new COSDictionary();

// acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);

acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);

doc.getDocumentCatalog().setAcroForm(acroForm);

COSDictionary cosDict1 = new COSDictionary();

COSArray rect1 = new COSArray();

rect1.add(new COSFloat(100));

rect1.add(new COSFloat(700));

rect1.add(new COSFloat(200));

rect1.add(new COSFloat(750));

cosDict1.setItem(COSName.RECT, rect1);

cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type

cosDict1.setItem(COSName.TYPE, COSName.ANNOT);

cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));

cosDict1.setItem(COSName.T, new COSString("tx1"));

cosDict1.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));

cosDict1.setItem(COSName.V, new COSString("Test Value1"));

PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

// textbox.setValue("Test Value");

page.getAnnotations().add(textbox.getWidget());

acroForm.getFields().add(textbox);

doc.save("C:\\PDF\\SampleTextbox.pdf");

doc.close();

}

}

我创建了一个文本字段,如上面的代码所示,并尝试使用textbox.setValue(“ Test

Value”);设置值。方法,但显示如下错误:

java.io.IOException: Error: Don't know how to calculate the position for non-simple fonts

at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.getTextPosition(PDAppearance.java:1037)

at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.insertGeneratedAppearance(PDAppearance.java:558)

at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.setAppearanceValue(PDAppearance.java:338)

at org.apache.pdfbox.pdmodel.interactive.form.PDVariableText.setValue(PDVariableText.java:131)

at sample.pdfbox.example.TestPDTextbox.Sample1(TestPDTextbox.java:54)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

为了解决问题#1,如果我使用cosDictionary属性(即cosDict1.setItem(COSName.V,new COSString(“ Test

Value1”)))设置textBox的值;

然后在Adobe Reader中,无法正确填充textBox的值。我必须单击文本框,然后才显示值,一旦我从字段中移出,值将再次变得不可见。

为了解决问题2,我需要将needAppearances标志设置为true,如下所示,然后在PDF中正确显示该字段值之后。但是在采用此解决方案之后,一旦用户更改字段值,我将无法提取/解析P​​DF字段,而我们再次解析此PDF。

这个问题存在于Adobe Reader中,在这里打开PDF时它也会发出一些信息,例如 将表单字段固定起来

。并且一旦我保存PDF并尝试解析acroform字段,就会发现所有字段都被重置或为null。不能提取任何字段名称或字段值。

因此,使用acroFormDict.setBoolean(COSName.getPDFName(“ NeedAppearances”),true);

代码中的代码似乎有风险,并且会在PDF解析中产生其他问题,因此无法使用。

COSDictionary acroFormDict = new COSDictionary(); 

acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);

acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);

doc.getDocumentCatalog().setAcroForm(acroForm);

我认为,我需要为文本字段设置PDAppearanceDictionary,但是我不知道这样做以及我是否需要为每个字段或在acroform级别进行设置。

请帮助我解决该问题。我正在使用PDFBOX版本1.8.10。

回答:

在上述问题中,我通过将页面资源添加到acroform中来修复了Issue#1,并为文本使用了正确的Default

Appearance字符串。现在,我不再需要将needsAppearance标志设置为true。

        PDFont font = PDType1Font.HELVETICA;

PDResources res = new PDResources();

String fontName = res.addFont(font);

String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

COSDictionary acroFormDict = new COSDictionary();

acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);

acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);

acroForm.setDefaultResources(res);

检查以下完整的更正代码:

import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;

import org.apache.pdfbox.cos.COSDictionary;

import org.apache.pdfbox.cos.COSFloat;

import org.apache.pdfbox.cos.COSName;

import org.apache.pdfbox.cos.COSString;

import org.apache.pdfbox.exceptions.COSVisitorException;

import org.apache.pdfbox.pdmodel.PDDocument;

import org.apache.pdfbox.pdmodel.PDPage;

import org.apache.pdfbox.pdmodel.PDResources;

import org.apache.pdfbox.pdmodel.font.PDFont;

import org.apache.pdfbox.pdmodel.font.PDType1Font;

import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;

import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;

import org.junit.Test;

public class TestPDTextbox {

@Test

public void Sample1 () throws IOException, COSVisitorException, BadLocationException {

PDDocument doc = new PDDocument();

PDPage page = new PDPage();

doc.addPage(page);

PDFont font = PDType1Font.HELVETICA;

PDResources res = new PDResources();

String fontName = res.addFont(font);

String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

COSDictionary acroFormDict = new COSDictionary();

acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);

acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);

acroForm.setDefaultResources(res);

doc.getDocumentCatalog().setAcroForm(acroForm);

COSDictionary cosDict1 = new COSDictionary();

COSArray rect1 = new COSArray();

rect1.add(new COSFloat(100));

rect1.add(new COSFloat(700));

rect1.add(new COSFloat(200));

rect1.add(new COSFloat(750));

cosDict1.setItem(COSName.RECT, rect1);

cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type

cosDict1.setItem(COSName.TYPE, COSName.ANNOT);

cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));

cosDict1.setItem(COSName.T, new COSString("tx1"));

cosDict1.setItem(COSName.DA, new COSString(defaultAppearance));

// cosDict1.setItem(COSName.V, new COSString("Test Value1"));

PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

textbox.setValue("Test Value");

page.getAnnotations().add(textbox.getWidget());

acroForm.getFields().add(textbox);

doc.save("C:\\PDF\\SampleTextbox.pdf");

doc.close();

}

}

以上是 在使用PDFBOX生成的PDF中,“保存的文本字段”值无法正确显示 的全部内容, 来源链接: utcz.com/qa/420760.html

回到顶部