Home > Enterprise >  PDFBOX - saveIncremental does not work with Multi widget form
PDFBOX - saveIncremental does not work with Multi widget form

Time:10-04

I have a PDTextField with two widgets. Setting value with saveIncremental does not work.

PDFBox Version - 2.0.24

Code to add PDTextField with multiple widgets with fill. Form fields in saved file disappear. I tried without objectsToWrite but it did not work.

My Sample Code:

    try (FileOutputStream output = new FileOutputStream("src/main/resources/Sample_form.pdf");
         PDDocument document = PDDocument.load(new File("src/main/resources/Sample.pdf"))) {

        PDFont font = PDType1Font.HELVETICA;
        PDResources resources = new PDResources();
        resources.put(COSName.HELV, font);

        PDAcroForm acroForm = new PDAcroForm(document);
        document.getDocumentCatalog().setAcroForm(acroForm);
        acroForm.setDefaultResources(resources);
        String defaultAppearanceString = "/Helv 0 Tf 0 g";
        acroForm.setDefaultAppearance(defaultAppearanceString);

        PDTextField textBox = new PDTextField(acroForm);
        textBox.setPartialName("SampleFieldMultiwidget");

        defaultAppearanceString = "/Helv 12 Tf 0 0 1 rg";
        textBox.setDefaultAppearance(defaultAppearanceString);

        acroForm.getFields().add(textBox);
        PDPage page1=document.getPage(0);
        PDPage page2=document.getPage(1);

        PDAnnotationWidget widget1 = new PDAnnotationWidget();
        PDRectangle rect = new PDRectangle(50, 750, 250, 50);
        widget1.setRectangle(rect);
        widget1.setPage(page1);
        widget1.setParent(textBox);

        PDAnnotationWidget widget2 = new PDAnnotationWidget();
        PDRectangle rect2 = new PDRectangle(200, 650, 100, 50);
        widget2.setRectangle(rect2);
        widget2.setPage(page2);
        widget2.setParent(textBox);

        List<PDAnnotationWidget> widgets = new ArrayList<>();
        widgets.add(widget1);
        widgets.add(widget2);
        textBox.setWidgets(widgets);

        widget1.setPrinted(true);
        widget2.setPrinted(true);

        page1.getAnnotations().add(widget1);
        page2.getAnnotations().add(widget2);

        document.save(output);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

And this for filling

  try (FileOutputStream output = new FileOutputStream("src/main/resources/Sample_form_filled.pdf");
         PDDocument document = PDDocument.load(new File("src/main/resources/Sample_form.pdf"))) {
        PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();

        PDTextField field = (PDTextField)acroForm.getField("SampleFieldMultiwidget");
        field.setValue("Sample Value");
        field.setReadOnly(true);

        COSDictionary fieldDictionary = field.getCOSObject();
        fieldDictionary.setNeedToBeUpdated(true);

        COSArray cosArray = (COSArray)field.getCOSObject().getDictionaryObject(COSName.KIDS);
        cosArray.setNeedToBeUpdated(true);

        for (int i = 0; i < cosArray.size(); i  ) {
            COSObject cosObject = (COSObject) cosArray.get(i);
            COSDictionary dictionary = (COSDictionary) cosObject.getDictionaryObject(COSName.AP);
            dictionary.setNeedToBeUpdated(true);
            COSStream stream = (COSStream) dictionary.getDictionaryObject(COSName.N);
            stream.setNeedToBeUpdated(true);

            COSDictionary dictionary2 = (COSDictionary) cosObject.getDictionaryObject(COSName.PARENT);
            while (dictionary2 != null) {
                dictionary2.setNeedToBeUpdated(true);
                dictionary2 = (COSDictionary) dictionary2.getDictionaryObject(COSName.PARENT);
            }
        }
        Set<COSDictionary> objectsToWrite = new HashSet<>();
        for (PDPage pdPage: document.getPages()) {
            objectsToWrite.add(pdPage.getCOSObject());
            objectsToWrite.add(field.getCOSObject());
        }
       //Added - post comment
            objectsToWrite.add(field.getWidgets().get(0).getAppearance().getCOSObject());
            objectsToWrite.add((COSDictionary) field.getWidgets().get(0).getAppearance().getNormalAppearance().getCOSObject());
            objectsToWrite.add(field.getWidgets().get(1).getAppearance().getCOSObject());
            objectsToWrite.add((COSDictionary) field.getWidgets().get(1).getAppearance().getNormalAppearance().getCOSObject());
        document.saveIncremental(output,objectsToWrite);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

What do I miss? Thanks!

Added.

Sample Files

Update: It is resolved. I missed setting widget appearance. Now renders on all viewers.

Thank you

CodePudding user response:

Adding appearance to widget resolved the issue.

        PDAppearanceDictionary pdAppearanceDictionary = new PDAppearanceDictionary();
        widget1.setAppearance(pdAppearanceDictionary);
        pdAppearanceDictionary.setNormalAppearance(new PDAppearanceStream(document));
  • Related