Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a button in PDF BOX?

I want to create a button in PDFBOX i.e., validate or reset button which will call some function of embedded javascript in PDF.

How can I create such button in PDFBOX?

I have tried following code with PDPushButton snippet but it is now working properly. Here when I click on button area, then tick mark symbol is displayed and toggles on every click. Also border is not getting displayed. Instead I want to display normal button having label and border around it.

I`m using pdfbox version 1.8.10.

PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);            

PDAcroForm acroForm = new PDAcroForm(doc);
        doc.getDocumentCatalog().setAcroForm(acroForm);

        PDActionJavaScript javascript = new PDActionJavaScript("function validate(index){ app.alert(index); }");
        doc.getDocumentCatalog().setOpenAction( javascript );

COSDictionary cosDict = new COSDictionary();
            COSArray rect = new COSArray();
            rect.add(new COSFloat(100));
            rect.add(new COSFloat(10));
            rect.add(new COSFloat(200));
            rect.add(new COSFloat(60));

            cosDict.setItem(COSName.RECT, rect);
            cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
            cosDict.setItem(COSName.TYPE, COSName.ANNOT);
            cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
            cosDict.setItem(COSName.T, new COSString("My Btn"));
            cosDict.setItem(COSName.V, new COSString("Validate"));
            cosDict.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));

            PDPushButton button = new PDPushButton(acroForm, cosDict);
            button.setValue("Validate Button");

            PDActionJavaScript tfJs = new PDActionJavaScript("validate("+index+");");
            PDAnnotationAdditionalActions tfAction = new PDAnnotationAdditionalActions();
            tfAction.setU(tfJs);
            button.getWidget().setActions(tfAction);

            PDGamma colourBlack = new PDGamma();
            PDAppearanceCharacteristicsDictionary fieldAppearance = 
                    new PDAppearanceCharacteristicsDictionary(cosDict);
            fieldAppearance.setBorderColour(colourBlack);
            button.getWidget().setAppearanceCharacteristics(fieldAppearance);

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

            acroForm.getFields().add(button);
like image 404
Nirav Patel Avatar asked Aug 27 '15 13:08

Nirav Patel


2 Answers

Following code generated proper button with borders and also invokes javascript function properly. Only issue is setting validate label on button. If anyone have solution to it, please provide your feedback.

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

        PDActionJavaScript javascript = new PDActionJavaScript("function validate(index){ app.alert(index); }");
        doc.getDocumentCatalog().setOpenAction( javascript );

        COSDictionary cosDict = new COSDictionary();
        COSArray rect = new COSArray();
        rect.add(new COSFloat(100));
        rect.add(new COSFloat(10));
        rect.add(new COSFloat(200));
        rect.add(new COSFloat(60));


        cosDict.setItem(COSName.RECT, rect);
        cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
        cosDict.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict.setItem(COSName.T, new COSString("Btn"+1));
        cosDict.setItem(COSName.V, new COSString("Validate"));
        cosDict.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));
        cosDict.setInt(COSName.FF, 65536); 

        PDPushButton button = new PDPushButton(acroForm, cosDict);
        button.setValue("Validate Button");

        PDActionJavaScript tfJs = new PDActionJavaScript("validate("+1+");");
        PDAnnotationAdditionalActions tfAction = new PDAnnotationAdditionalActions();
        tfAction.setU(tfJs);
        button.getWidget().setActions(tfAction);

        PDGamma colourBlack = new PDGamma();
        PDAppearanceCharacteristicsDictionary fieldAppearance = 
                new PDAppearanceCharacteristicsDictionary(new COSDictionary());
        fieldAppearance.setBorderColour(colourBlack);
        button.getWidget().setAppearanceCharacteristics(fieldAppearance);

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

        acroForm.getFields().add(button);

         doc.save("/path");
         doc.close();
like image 68
Nirav Patel Avatar answered Nov 19 '22 17:11

Nirav Patel


Here is the solution of "How to set caption for PDPushButton in PDFBox 2.0.0"

For caption value needs to show for pushbutton, you needs to call setNormalCaption("captionStr") of the PDAppearanceCharacteristicsDictionary.
Here is the code for Button Caption Value with text color change:

    PDDocument doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage(page);

    try {
        COSDictionary acroFormDict = new COSDictionary();
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.FIELDS, new COSArray());

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        doc.getDocumentCatalog().setAcroForm(acroForm);

        PDActionJavaScript javascript = new PDActionJavaScript(
                "function validate(index){ app.alert(index); }");
        doc.getDocumentCatalog().setOpenAction(javascript);

        COSDictionary cosDict = new COSDictionary();
        COSArray rect = new COSArray();
        rect.add(new COSFloat(50));
        rect.add(new COSFloat(775));
        rect.add(new COSFloat(100));
        rect.add(new COSFloat(750));
        cosDict.setItem(COSName.RECT, rect);
        cosDict.setItem(COSName.FT, COSName.getPDFName("Btn"));
        cosDict.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict.setItem(COSName.T, new COSString("ClickMe"));
        //cosDict.setItem(COSName.V, new COSString("Click Me"));
        cosDict.setItem(COSName.DA, new COSString("/F0 6 Tf 0 g 1 1 1 rg "));

        PDPushButton button = new PDPushButton(acroForm);

        PDActionJavaScript tfJs = new PDActionJavaScript("validate("+1+");");
        PDAnnotationAdditionalActions tfAction = new PDAnnotationAdditionalActions();
        tfAction.setU(tfJs);
        button.getWidgets().get(0).setActions(tfAction);

    //  button.setReadOnly(true);
        button.getCOSObject().addAll(cosDict);
        acroForm.getFields().add(button);

        PDAnnotationWidget widget = button.getWidgets().get(0);

        PDAppearanceCharacteristicsDictionary fieldAppearance = 
                new PDAppearanceCharacteristicsDictionary(new COSDictionary());
        COSArray borderColorArray = new COSArray();
        borderColorArray.add(new COSFloat((float) (141f/255f)));
        borderColorArray.add(new COSFloat((float) (179f/255f)));
        borderColorArray.add(new COSFloat((float) (226f/255f)));
        PDColor blue = new PDColor(borderColorArray, PDDeviceRGB.INSTANCE);
        fieldAppearance.setBorderColour(blue);
        fieldAppearance.setBackground(blue);
        fieldAppearance.setNormalCaption("Click Me");

        widget.setAppearanceCharacteristics(fieldAppearance);
        page.getAnnotations().add(widget);


        File file = new File("/path");
        System.out.println("File created");
        FileOutputStream fOut = new FileOutputStream(file);
        doc.save(fOut);
        doc.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

Here:

cosDict.setItem(COSName.V, new COSString("Click Me")); 

And here:

button.setValue("Click Me");

Will not work.

For this, you needs to add below line:

fieldAppearance.setNormalCaption("Click Me");

Above example is the solution for PDFBox2.0.
In PDFBox 1.8.11, i think this will also going to work. :)

like image 3
Niyati Shah Avatar answered Nov 19 '22 15:11

Niyati Shah