Saved text field value does not display correctly in PDF format generated using PDFBOX

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(); } } 

Issue # 1 I created one text box, as shown in the above code, and tried to set the value using textbox.setValue ("Test Value"); but it gives an error as shown below:

 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) 

Issue No. 2

To fix problem # 1, if I set the value of textBox using the cosDictionary property i.e. cosDict1.setItem (COSName.V, new COSString ("Test Value1"));

Then, in Adobe Reader, the textBox value is incorrectly populated. I have to click on the text field and then only the value will appear, and as soon as I exit the field, the value will become invisible again.

Issue # 3

To fix problem # 2, I need to set the needAppearances flag to true, as shown below, and after that the field value displays correctly in PDF. But after this solution, I will not be able to extract / parse the PDF field back once the user changes the value of the field and we will analyze this PDF file again.

Note. - This problem exists in Adobe Reader, here, opening the PDF, it gives some message, as well as the correction of the form fields. And as soon as I save the PDF and try to parse the acroform fields, all the fields will be reset or null. No field name or field values ​​can be retrieved.

So using acroFormDict.setBoolean (COSName.getPDFName ("NeedAppearances"), true); in the code seems risky and creates another problem in parsing PDF, so it can not be used.

 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); 

I think I need to set PDAppearanceDictionary for text fields, but I don’t know what to do, and whether to set for each field or at acroform level.

Please help me in this matter, how can I resolve it. I am using PDFBOX version 1.8.10.

+2
source share
1 answer

In the above question, I fixed issue # 1 by adding page resources for acroform and using the Default Appearance line for the text. Now I do not need to set the value requireAppearance flag 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); 

Check all corrected code below:

 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(); } } 
+1
source

Source: https://habr.com/ru/post/1232698/


All Articles