javaitextdynamicpdf

How to generate PDF having HTML like capabilities using Java


I need to create PDF using some java API which has the capabilities like HTML. Basically, I want to create a form which can take input from users, perform some basic client side validations and also generate this PDF programmatically using Java. I am also looking for rich HTML like features like expand, collapse, hyperlinks, add a section on a button click etc. So basically I am trying to create an HTML like page but within PDF.

I have tried using itext but able to only to do only handful of things and not able to add dynamism into PDF. Is there any tool/API which supports this?


Solution

  • PDF itself allows you to embed (a subset of) javascript.

    This embedded code can be linked to document events (e.g. opening the document) or specific form elements (e.g. clicking a button, changing the text in a text-input field).

    This is a page from their website entitled 'Making a PDF interactive' which focusses on adding form elements.

    The book (iText in Action) by Bruno Lowagie (original founder of iText) also goes in great detail. It even shows how to program a calculator in a PDF document, page 232.

    I'm just going to copy-paste the relevant section here.

    Listing 7.29 Calculator

    public void addTextField(PdfWriter writer, Rectangle rect, String name) {
        PdfFormField field = PdfFormField.createTextField(writer, false, false, 0);
         field.setFieldName(name);
         field.setWidget(rect, PdfAnnotation.HIGHLIGHT_NONE);
         field.setQuadding(PdfFormField.Q_RIGHT);
         field.setFieldFlags(PdfFormField.FF_READ_ONLY);
         writer.addAnnotation(field);
    }    
    
    public void addPushButton(PdfWriter writer, Rectangle rect, String btn, String script) {
        float w = rect.getWidth();
        float h = rect.getHeight();
        PdfFormField pushbutton = PdfFormField.createPushButton(writer);
        pushbutton.setFieldName("btn_" + btn);
        pushbutton.setWidget(rect, PdfAnnotation.HIGHLIGHT_PUSH);
        PdfContentByte cb = writer.getDirectContent();
        pushbutton.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, createAppearance(cb, btn, BaseColor.GRAY, w, h));
        pushbutton.setAppearance(PdfAnnotation.APPEARANCE_ROLLOVER, createAppearance(cb, btn, BaseColor.RED, w, h));
        pushbutton.setAppearance(PdfAnnotation.APPEARANCE_DOWN, createAppearance(cb, btn, BaseColor.BLUE, w, h));
        pushbutton.setAdditionalActions(PdfName.U, PdfAction.javaScript(script, writer));
        pushbutton.setAdditionalActions(PdfName.E, PdfAction.javaScript( "this.showMove('" + btn + "');", writer));
        pushbutton.setAdditionalActions(PdfName.X, PdfAction.javaScript( "this.showMove(' ');", writer));
        writer.addAnnotation(pushbutton);
    }
    
    public PdfAppearance createAppearance(PdfContentByte cb, String btn, BaseColor color, float w, float h) {
        PdfAppearance app = cb.createAppearance(w, h);
        app.setColorFill(color);
        app.rectangle(2, 2, w - 4, h - 4);
        app.fill();
        app.beginText();
        app.setColorFill(BaseColor.BLACK);
        app.setFontAndSize(bf, h / 2);
        app.showTextAligned(Element.ALIGN_CENTER, btn, w / 2, h / 4, 0);
        app.endText();
        return app;
    }