Hi,

flatten() will flatten the form fields but without refreshing the fields 
appearance i.e. how you see it on the form. Now, as NeedAppearances is set to 
true, the prior setValue() call also didn't refresh the fields appearance as 
the  NeedAppearances flag tells the viewer to handle that.

There are two options: set the NeedAppearances flag to false using 
PDAcroForm.setNeedAppearances(false) or use flatten(List<PDField> fields, 
boolean refreshAppearances).

Unfortunately there is an issue with the form as it doesn't contain a /DR entry 
(i.e. it doesn't specify which resources, most important the fonts, to use).

        Exception in thread "main" java.lang.IllegalArgumentException: /DR is a 
required entry

PDFBox doesn't yet have a fall back see PDFBOX-2662.What you could do is 
generate an appropriate entry yourself.

        PDResources dr = new PDResources();             
        dr.put(COSName.getPDFName("Courier"), PDType1Font.COURIER);
        dr.put(COSName.getPDFName("Helvetica"), PDType1Font.HELVETICA); 
        pdAcroForm.setDefaultResources(dr);

That reveals another issue 

Exception in thread "main" java.lang.NullPointerException
        at 
org.apache.pdfbox.pdmodel.PDPageContentStream.<init>(PDPageContentStream.java:195)

Which is caused as the annotations are not connected to a page.

The can be resolved by 

                for (PDPage page : pdDoc.getPages()) {
                        for (PDAnnotation annot : page.getAnnotations()) {
                                annot.setPage(page);
                        }
                }

Finally setReadOnly() needn't be set for the field as after flatten() there are 
no more fields.

So the final code looks like that


                try {
                        File myFile = new File(template);
                        PDDocument pdDoc = PDDocument.load( myFile );
                        PDDocumentCatalog pdCatalog = 
pdDoc.getDocumentCatalog();
                        PDAcroForm pdAcroForm = pdCatalog.getAcroForm();
                        
                        // set the NeedApperances flag
                        pdAcroForm.setNeedAppearances(false);
                        
                        // correct the missing page link for the annotations
                        for (PDPage page : pdDoc.getPages()) {
                                for (PDAnnotation annot : 
page.getAnnotations()) {
                                        annot.setPage(page);
                                }
                        }
                        
                        // Add the missing resources to the form
                        PDResources dr = new PDResources();             
                        dr.put(COSName.getPDFName("Courier"), 
PDType1Font.COURIER);
                        dr.put(COSName.getPDFName("Helvetica"), 
PDType1Font.HELVETICA);
                        
                        pdAcroForm.setDefaultResources(dr);                     
                        
                        PDField field = pdAcroForm.getField("Make");
                        field.setValue("Jeep");
                        field = pdAcroForm.getField("Model");
                        field.setValue("Grand Cherokee");
                        field = pdAcroForm.getField("Check Box1");              
        
                        field.setValue("Yes");
                        pdAcroForm.flatten();
                        pdDoc.save(flattened);
                        pdDoc.close();
                }
                catch (Exception e) {
                        e.printStackTrace();
                }


BR
Maruan


> Am 31.03.2016 um 18:54 schrieb Barry Neu <[email protected]>:
> 
> 
>> 
> <alabama-abandoned-motor-vehicle-bill-of-sale.pdf>
>> 
>> 
>> Hello.
>> I’m trying out PDFBox 2.0 for an application where I need to flatten forms 
>> with data collected from a user interface.
>> Using the below code, I set some sample fields and set the read only flag to 
>> true. The resulting output has the data populated on the form but the 
>> CheckBox is still editable.
>> When using the PDAcroForm.flatten() method, the CheckBox is not editable, 
>> but the values set in the Text fields do not appear populated on the 
>> resulting form.
>> Using Java 1.7 on OSX.
>> Sample form attached.
>> 
>> Probably something simple I am missing. Any help appreciated.
>> 
>> 
>> import java.io <http://java.io/>.*;
>> import java.util.Collection;
>> import java.util.ArrayList;
>> import org.apache.pdfbox.pdmodel.*;
>> import org.apache.pdfbox.pdmodel.common.COSArrayList;
>> import org.apache.pdfbox.pdmodel.font.PDFont;
>> import org.apache.pdfbox.pdmodel.font.PDType1Font;
>> import org.apache.pdfbox.pdmodel.interactive.form.*;
>> import org.apache.pdfbox.cos.COSDictionary;
>> import org.apache.pdfbox.cos.COSArray;
>> import org.apache.pdfbox.cos.COSBase;
>> 
>> public class PdfFiller {
>> 
>>      public static void main(String[] args) {
>>              String template  = 
>> ā€œ/mypath/alabama-abandoned-motor-vehicle-bill-of-sale.pdf";
>>              String flattened = 
>> ā€œ/mypath/FILLED-alabama-abandoned-motor-vehicle-bill-of-sale.pdf";
>>              try {
>>                      File myFile = new File(template);
>>                      PDDocument pdDoc = PDDocument.load( myFile );
>>                      PDDocumentCatalog pdCatalog = 
>> pdDoc.getDocumentCatalog();
>>                      PDAcroForm pdAcroForm = pdCatalog.getAcroForm();
>>                      PDField field = pdAcroForm.getField("Make");
>>                      field.setValue("Jeep");
>>                      field.setReadOnly(true);
>>                      field = pdAcroForm.getField("Model");
>>                      field.setValue("Grand Cherokee");
>>                      field.setReadOnly(true);
>>                      field = pdAcroForm.getField("Check Box1");              
>>         
>>                      field.setValue("Yes");
>>                      field.setReadOnly(true);
>>                      //pdAcroForm.flatten();  //uncommenting line results in 
>> missing values in text fields
>>                      pdDoc.save(flattened);
>>                      pdDoc.close();
>>              }
>>              catch (Exception e) {
>>                      e.printStackTrace();
>>              }
>>      }
>> }
>> 
> 

Reply via email to