Chapter 8: Filling out interactive forms

These examples were written in the context of Chapter 8 of the book "iText in Action - Second Edition".

Files: 
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Utilities;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfAppearance;
import com.itextpdf.text.pdf.PdfBorderDictionary;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.PushbuttonField;
import com.itextpdf.text.pdf.RadioCheckField;
 
public class Buttons {
 
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/buttons.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/buttons_filled.pdf";
    /** Path to a JavaScript resource. */
    public static final String RESOURCE = "resources/js/buttons.js";
    /** Path to an image used as button icon. */
    public static final String IMAGE = "resources/img/info.png";
    /** Possible values of a radio field / checkboxes */
    public static final String[] LANGUAGES = { "English", "German", "French", "Spanish", "Dutch" };
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter writer =
            PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        // add the JavaScript
        writer.addJavaScript(Utilities.readFileToString(RESOURCE));
        // add the radio buttons
        PdfContentByte canvas = writer.getDirectContent();
        Font font = new Font(FontFamily.HELVETICA, 18);
        Rectangle rect;
        PdfFormField field;
        PdfFormField radiogroup = PdfFormField.createRadioButton(writer, true);
        radiogroup.setFieldName("language");
        RadioCheckField radio;
        for (int i = 0; i < LANGUAGES.length; i++) {
            rect = new Rectangle(40, 806 - i * 40, 60, 788 - i * 40);
            radio = new RadioCheckField(writer, rect, null, LANGUAGES[i]);
            radio.setBorderColor(GrayColor.GRAYBLACK);
            radio.setBackgroundColor(GrayColor.GRAYWHITE);
            radio.setCheckType(RadioCheckField.TYPE_CIRCLE);
            field = radio.getRadioField();
            radiogroup.addKid(field);
            ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
                new Phrase(LANGUAGES[i], font), 70, 790 - i * 40, 0);
        }
        writer.addAnnotation(radiogroup);
        // Add the check boxes
        PdfAppearance[] onOff = new PdfAppearance[2];
        onOff[0] = canvas.createAppearance(20, 20);
        onOff[0].rectangle(1, 1, 18, 18);
        onOff[0].stroke();
        onOff[1] = canvas.createAppearance(20, 20);
        onOff[1].setRGBColorFill(255, 128, 128);
        onOff[1].rectangle(1, 1, 18, 18);
        onOff[1].fillStroke();
        onOff[1].moveTo(1, 1);
        onOff[1].lineTo(19, 19);
        onOff[1].moveTo(1, 19);
        onOff[1].lineTo(19, 1);
        onOff[1].stroke();
        RadioCheckField checkbox;
        for (int i = 0; i < LANGUAGES.length; i++) {
            rect = new Rectangle(180, 806 - i * 40, 200, 788 - i * 40);
            checkbox = new RadioCheckField(writer, rect, LANGUAGES[i], "Yes");
            field = checkbox.getCheckField();
            field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", onOff[0]);
            field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Yes", onOff[1]);
            writer.addAnnotation(field);
            ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
                new Phrase(LANGUAGES[i], font), 210, 790 - i * 40, 0);
        }
        // Add the push button
        rect = new Rectangle(300, 806, 370, 788);
        PushbuttonField button = new PushbuttonField(writer, rect, "Buttons");
        button.setBackgroundColor(new GrayColor(0.75f));
        button.setBorderColor(GrayColor.GRAYBLACK);
        button.setBorderWidth(1);
        button.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
        button.setTextColor(GrayColor.GRAYBLACK);
        button.setFontSize(12);
        button.setText("Push me");
        button.setLayout(PushbuttonField.LAYOUT_ICON_LEFT_LABEL_RIGHT);
        button.setScaleIcon(PushbuttonField.SCALE_ICON_ALWAYS);
        button.setProportionalIcon(true);
        button.setIconHorizontalAdjustment(0);
        button.setImage(Image.getInstance(IMAGE));
        field = button.getField();
        field.setAction(PdfAction.javaScript("this.showButtonState()", writer));
        writer.addAnnotation(field);
        // step 5
        document.close();
 
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        String[] radiostates = form.getAppearanceStates("language");
        form.setField("language", radiostates[4]);
        for (int i = 0; i < LANGUAGES.length; i++) {
            String[] checkboxstates = form.getAppearanceStates("English");
            form.setField(LANGUAGES[i], checkboxstates[i % 2 == 0 ? 1 : 0]);
        }
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        Buttons buttons = new Buttons();
        buttons.createPdf(RESULT1);
        buttons.manipulatePdf(RESULT1, RESULT2);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RadioCheckField;
 
public class RadioButtons {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part2/chapter08/radiobuttons.pdf";
    /** Possible values of a Choice field. */
    public static final String[] LANGUAGES = { "English", "German", "French", "Spanish", "Dutch" };
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter writer =
            PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
        // create a radio field spanning different pages
        PdfFormField radiogroup = PdfFormField.createRadioButton(writer, true);
        radiogroup.setFieldName("language");
        Rectangle rect = new Rectangle(40, 806, 60, 788);
        RadioCheckField radio;
        PdfFormField radiofield;
        for (int page = 0; page < LANGUAGES.length; ) {
            radio = new RadioCheckField(writer, rect, null, LANGUAGES[page]);
            radio.setBackgroundColor(new GrayColor(0.8f));
            radiofield = radio.getRadioField();
            radiofield.setPlaceInPage(++page);
            radiogroup.addKid(radiofield);
        }
        writer.addAnnotation(radiogroup);
        // add the content
        for (int i = 0; i < LANGUAGES.length; i++) {
            cb.beginText();
            cb.setFontAndSize(bf, 18);
            cb.showTextAligned(Element.ALIGN_LEFT, LANGUAGES[i], 70, 790, 0);
            cb.endText();
            document.newPage();
        }
        // step 5
        document.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new RadioButtons().createPdf(RESULT);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PushbuttonField;
 
import part2.chapter07.Advertisement;
 
public class ReplaceIcon {
 
    /** Image that will be used as an icon. */
    public static final String RESOURCE = "resources/img/iia2.jpg";
    /** The resulting PDF. */
    public static final String RESULT = "results/part2/chapter08/advertisement2.pdf";
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        PushbuttonField ad = form.getNewPushbuttonFromField("advertisement");
        ad.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
        ad.setProportionalIcon(true);
        ad.setImage(Image.getInstance(RESOURCE));
        form.replacePushbuttonField("advertisement", ad.getField());
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws SQLException
     * @throws DocumentException
     * @throws IOException
     */
    public static void main(String[] args) throws SQLException, DocumentException, IOException {
        Advertisement.main(args);
        new ReplaceIcon().manipulatePdf(Advertisement.RESULT, RESULT);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfBorderDictionary;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.pdf.TextField;
 
public class TextFields implements PdfPCellEvent {
 
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/text_fields.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/text_filled.pdf";
    /** The text field index of a TextField that needs to be added to a cell. */
    protected int tf;
 
    /**
     * Creates a cell event that will add a text field to a cell.
     * @param tf a text field index.
     */
    public TextFields(int tf) {
        this.tf = tf;
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.setField("text_1", "Bruno Lowagie");
        form.setFieldProperty("text_2", "fflags", 0, null);
        form.setFieldProperty("text_2", "bordercolor", BaseColor.RED, null);
        form.setField("text_2", "bruno");
        form.setFieldProperty("text_3", "clrfflags", TextField.PASSWORD, null);
        form.setFieldProperty("text_3", "setflags", PdfAnnotation.FLAGS_PRINT, null);
        form.setField("text_3", "12345678", "xxxxxxxx");
        form.setFieldProperty("text_4", "textsize", new Float(12), null);
        form.regenerateField("text_4");
        stamper.close();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException 
     */
    public void createPdf(String filename) throws DocumentException, IOException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfPCell cell;
        PdfPTable table = new PdfPTable(2);
        table.setWidths(new int[]{ 1, 2 });
 
        table.addCell("Name:");
        cell = new PdfPCell();
        cell.setCellEvent(new TextFields(1));
        table.addCell(cell);
 
        table.addCell("Loginname:");
        cell = new PdfPCell();
        cell.setCellEvent(new TextFields(2));
        table.addCell(cell);
 
        table.addCell("Password:");
        cell = new PdfPCell();
        cell.setCellEvent(new TextFields(3));
        table.addCell(cell);
 
        table.addCell("Reason:");
        cell = new PdfPCell();
        cell.setCellEvent(new TextFields(4));
        cell.setFixedHeight(60);
        table.addCell(cell);
 
        document.add(table);
        // step 5
        document.close();
 
    }
 
    /**
     * Creates and adds a text field that will be added to a cell.
     * @see com.itextpdf.text.pdf.PdfPCellEvent#cellLayout(com.itextpdf.text.pdf.PdfPCell,
     *      com.itextpdf.text.Rectangle, com.itextpdf.text.pdf.PdfContentByte[])
     */
    public void cellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases) {
        PdfWriter writer = canvases[0].getPdfWriter();
        TextField text = new TextField(writer, rectangle,
                String.format("text_%s", tf));
        text.setBackgroundColor(new GrayColor(0.75f));
        switch(tf) {
        case 1:
            text.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
            text.setText("Enter your name here...");
            text.setFontSize(0);
            text.setAlignment(Element.ALIGN_CENTER);
            text.setOptions(TextField.REQUIRED);
            break;
        case 2:
            text.setMaxCharacterLength(8);
            text.setOptions(TextField.COMB);
            text.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
            text.setBorderColor(BaseColor.BLUE);
            text.setBorderWidth(2);
            break;
        case 3:
            text.setBorderStyle(PdfBorderDictionary.STYLE_INSET);
            text.setOptions(TextField.PASSWORD);
            text.setVisibility(TextField.VISIBLE_BUT_DOES_NOT_PRINT);
            break;
        case 4:
            text.setBorderStyle(PdfBorderDictionary.STYLE_DASHED);
            text.setBorderColor(BaseColor.RED);
            text.setBorderWidth(2);
            text.setFontSize(8);
            text.setText(
                "Enter the reason why you want to win a free accreditation for the Foobar Film Festival");
            text.setOptions(TextField.MULTILINE | TextField.REQUIRED);
            break;
        }
        try {
            PdfFormField field = text.getTextField();
            if (tf == 3) {
                field.setUserName("Choose a password");
            }
            writer.addAnnotation(field);
        }
        catch(IOException ioe) {
            throw new ExceptionConverter(ioe);
        }
        catch(DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws DocumentException, IOException {
        TextFields example = new TextFields(0);
        example.createPdf(RESULT1);
        example.manipulatePdf(RESULT1, RESULT2);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.TextField;
 
public class TextFieldFonts {
 
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/unicode_field_1.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/unicode_field_2.pdf";
    /** The resulting PDF. */
    public static final String RESULT3 = "results/part2/chapter08/unicode_field_3.pdf";
    /** The resulting PDF. */
    public static final String RESULT4 = "results/part2/chapter08/unicode_field_4.pdf";
    /** The resulting PDF. */
    public static final String RESULT5 = "results/part2/chapter08/unicode_field_5.pdf";
    /** The resulting PDF. */
    public static final String RESULT6 = "results/part2/chapter08/unicode_field_6.pdf";
    /** The resulting PDF. */
    public static final String RESULT7 = "results/part2/chapter08/unicode_field_7.pdf";
    /** The resulting PDF. */
    public static final String RESULT8 = "results/part2/chapter08/unicode_field_8.pdf";
    /** A String containing Chinese characters/ */
    public static final String TEXT = "These are the protagonists in 'Hero', a movie by Zhang Yimou:\n"
        + "\u7121\u540d (Nameless), \u6b98\u528d (Broken Sword), "
        + "\u98db\u96ea (Flying Snow), \u5982\u6708 (Moon), "
        + "\u79e6\u738b (the King), and \u9577\u7a7a (Sky).";
    /** A String containing Korean characters. */
    public static final String BINJIP = "The Korean title of the movie 3-Iron is \ube48\uc9d1 (Bin-Jip)";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @param appearacnes sets the need appearances flag if true
     * @param font adds a substitution font if true
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename, boolean appearances, boolean font)
        throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        writer.getAcroForm().setNeedAppearances(appearances);
        TextField text = new TextField(writer, new Rectangle(36, 806, 559, 780), "description");
        text.setOptions(TextField.MULTILINE);
        if (font) {
            BaseFont unicode =
                BaseFont.createFont("c:/windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            text.setExtensionFont(BaseFont.createFont());
            ArrayList<BaseFont> list = new ArrayList<BaseFont>();
            list.add(unicode);
            text.setSubstitutionFonts(list);
        }
        text.setText(TEXT);
        writer.addAnnotation(text.getTextField());
        // step 5
        document.close();
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.setField("description", BINJIP);
        stamper.close();
        reader.close();
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdfFont1(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        BaseFont unicode =
            BaseFont.createFont("HYSMyeongJoStd-Medium", "UniKS-UCS2-H", BaseFont.NOT_EMBEDDED);
        form.setFieldProperty("description", "textfont", unicode, null);
        form.setField("description", BINJIP);
        stamper.close();
        reader.close();
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdfFont2(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        BaseFont unicode =
            BaseFont.createFont("c:/windows/fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        form.addSubstitutionFont(unicode);
        form.setField("description", BINJIP);
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        TextFieldFonts example = new TextFieldFonts();
        example.createPdf(RESULT1, false, false);
        example.createPdf(RESULT2, true, false);
        example.createPdf(RESULT3, false, true);
        example.manipulatePdf(RESULT1, RESULT4);
        example.manipulatePdf(RESULT2, RESULT5);
        example.manipulatePdf(RESULT3, RESULT6);
        example.manipulatePdfFont1(RESULT3, RESULT7);
        example.manipulatePdfFont2(RESULT3, RESULT8);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.TextField;
 
public class TextFieldActions {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part2/chapter08/field_actions.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        TextField date = new TextField(writer, new Rectangle(36, 806, 126, 780), "date");
        date.setBorderColor(new GrayColor(0.2f));
        PdfFormField datefield = date.getTextField();
        datefield.setAdditionalActions(PdfName.V, PdfAction.javaScript(
                "AFDate_FormatEx( 'dd-mm-yyyy' );", writer));
        writer.addAnnotation(datefield);
        TextField name = new TextField(writer, new Rectangle(130, 806, 256, 780), "name");
        name.setBorderColor(new GrayColor(0.2f));
        PdfFormField namefield = name.getTextField();
        namefield.setAdditionalActions(PdfName.FO, PdfAction.javaScript(
                "app.alert('name field got the focus');", writer));
        namefield.setAdditionalActions(PdfName.BL, PdfAction.javaScript(
                "app.alert('name lost the focus');", writer));
        namefield.setAdditionalActions(PdfName.K, PdfAction.javaScript(
                "event.change = event.change.toUpperCase();", writer));
        writer.addAnnotation(namefield);
        // step 5
        document.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new TextFieldActions().createPdf(RESULT);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfBorderDictionary;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.pdf.TextField;
 
public class ChoiceFields implements PdfPCellEvent {
 
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/choice_fields.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/choice_filled.pdf";
    /** A choice field index. */
    protected int cf;
    /** An array with possible languages for a choice field. */
    public static final String[] LANGUAGES =
        { "English", "German", "French", "Spanish", "Dutch" };
    /** An array with export values for possible languages in a choice field. */
    public static final String[] EXPORTVALUES =
        { "EN", "DE", "FR", "ES", "NL" };
 
    /**
     * Creates a cell event that adds a Choice field to a cell.
     * @param cf a choice field index
     */
    public ChoiceFields(int cf) {
        this.cf = cf;
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.setField("choice_1", "NL");
        form.setListSelection("choice_2", new String[]{"German", "Spanish"});
        String[] languages = form.getListOptionDisplay("choice_3");
        String[] exportvalues = form.getListOptionExport("choice_3");
        int n = languages.length;
        String[] new_languages = new String[n + 2];
        String[] new_exportvalues = new String[n + 2];
        for (int i = 0; i < n; i++) {
            new_languages[i] = languages[i];
            new_exportvalues[i] = exportvalues[i];
        }
        new_languages[n] = "Chinese";
        new_exportvalues[n] = "CN";
        new_languages[n + 1] = "Japanese";
        new_exportvalues[n + 1] = "JP";
        form.setListOption("choice_3", new_exportvalues, new_languages);
        form.setField("choice_3", "CN");
        form.setField("choice_4", "Japanese");
        stamper.close();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfPCell cell;
        PdfPCell space;
        space = new PdfPCell();
        space.setBorder(Rectangle.NO_BORDER);
        space.setColspan(2);
        space.setFixedHeight(8);
        PdfPTable table = new PdfPTable(2);
        table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
        table.addCell("Language of the movie:");
        cell = new PdfPCell();
        cell.setCellEvent(new ChoiceFields(1));
        table.addCell(cell);
        table.addCell(space);
        table.addCell("Subtitle languages:");
        cell = new PdfPCell();
        cell.setCellEvent(new ChoiceFields(2));
        cell.setFixedHeight(70);
        table.addCell(cell);
        table.addCell(space);
        table.addCell("Select preferred language:");
        cell = new PdfPCell();
        cell.setCellEvent(new ChoiceFields(3));
        table.addCell(cell);
        table.addCell(space);
        table.addCell("Language of the director:");
        cell = new PdfPCell();
        cell.setCellEvent(new ChoiceFields(4));
        table.addCell(cell);
        document.add(table);
        // step 5
        document.close();
 
    }
 
    /**
     * Creates a choice field and adds it to a cell.
     * see com.itextpdf.text.pdf.PdfPCellEvent#cellLayout(com.itextpdf.text.pdf.PdfPCell, 
     *     com.itextpdf.text.Rectangle, com.itextpdf.text.pdf.PdfContentByte[])
     */
    public void cellLayout(PdfPCell cell, Rectangle rectangle,
            PdfContentByte[] canvases) {
        PdfWriter writer = canvases[0].getPdfWriter();
        TextField text = new TextField(writer, rectangle,
                String.format("choice_%s", cf));
        try {
            switch(cf) {
            case 1:
                text.setChoices(LANGUAGES);
                text.setChoiceExports(EXPORTVALUES);
                text.setChoiceSelection(2);
                writer.addAnnotation(text.getListField());
                break;
            case 2:
                text.setChoices(LANGUAGES);
                text.setBorderColor(BaseColor.GREEN);
                text.setBorderStyle(PdfBorderDictionary.STYLE_DASHED);
                text.setOptions(TextField.MULTISELECT);
                ArrayList<Integer> selections = new ArrayList<Integer>();
                selections.add(0);
                selections.add(2);
                text.setChoiceSelections(selections);
                PdfFormField field = text.getListField();
                writer.addAnnotation(field);
                break;
            case 3:
                text.setBorderColor(BaseColor.RED);
                text.setBackgroundColor(BaseColor.GRAY);
                text.setChoices(LANGUAGES);
                text.setChoiceExports(EXPORTVALUES);
                text.setChoiceSelection(4);
                writer.addAnnotation(text.getComboField());
                break;
            case 4:
                text.setChoices(LANGUAGES);
                text.setOptions(TextField.EDIT);
                writer.addAnnotation(text.getComboField());
                break;
            }
        }
        catch(IOException ioe) {
            throw new ExceptionConverter(ioe);
        }
        catch(DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        ChoiceFields fields = new ChoiceFields(0);
        fields.createPdf(RESULT1);
        fields.manipulatePdf(RESULT1, RESULT2);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.TextField;
 
public class Subscribe {
 
    /** The resulting PDF. */
    public static final String FORM = "results/part2/chapter08/subscribe.pdf";
    /** The resulting PDFs. */
    public static final String RESULT = "results/part2/chapter08/filled_form_%d.pdf";
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @param cache a map that will be used to cache text field information
     * @param name the name of a person
     * @param login the login name of the same person
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest,
        HashMap<String,TextField> cache, String name, String login)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.setFieldCache(cache);
        form.setExtraMargin(2, 0);
        form.removeField("personal.password");
        form.setField("personal.name", name);
        form.setField("personal.loginname", login);
        form.renameField("personal.reason", "personal.motivation");
        form.setFieldProperty("personal.loginname", "setfflags", TextField.READ_ONLY, null);
        stamper.setFormFlattening(true);
        stamper.partialFormFlattening("personal.name");
        stamper.close();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfFormField personal = PdfFormField.createEmpty(writer);
        personal.setFieldName("personal");
        PdfPTable table = new PdfPTable(3);
        PdfPCell cell;
 
        table.addCell("Your name:");
        cell = new PdfPCell();
        cell.setColspan(2);
        TextField field = new TextField(writer, new Rectangle(0, 0), "name");
        field.setFontSize(12);
        cell.setCellEvent(new ChildFieldEvent(personal, field.getTextField(), 1));
        table.addCell(cell);
        table.addCell("Login:");
        cell = new PdfPCell();
        field = new TextField(writer, new Rectangle(0, 0), "loginname");
        field.setFontSize(12);
        cell.setCellEvent(new ChildFieldEvent(personal, field.getTextField(), 1));
        table.addCell(cell);
        cell = new PdfPCell();
        field = new TextField(writer, new Rectangle(0, 0), "password");
        field.setOptions(TextField.PASSWORD);
        field.setFontSize(12);
        cell.setCellEvent(new ChildFieldEvent(personal, field.getTextField(), 1));
        table.addCell(cell);
        table.addCell("Your motivation:");
        cell = new PdfPCell();
        cell.setColspan(2);
        cell.setFixedHeight(60);
        field = new TextField(writer, new Rectangle(0, 0), "reason");
        field.setOptions(TextField.MULTILINE);
        field.setFontSize(12);
        cell.setCellEvent(new ChildFieldEvent(personal, field.getTextField(), 1));
        table.addCell(cell);
        document.add(table);
        writer.addAnnotation(personal);
        // step 5
        document.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        Subscribe subscribe = new Subscribe();
        subscribe.createPdf(FORM);
        HashMap<String,TextField> fieldCache = new HashMap<String,TextField>();
        subscribe.manipulatePdf(FORM, String.format(RESULT, 1), fieldCache, "Bruno Lowagie", "blowagie");
        subscribe.manipulatePdf(FORM, String.format(RESULT, 2), fieldCache, "Paulo Soares", "psoares");
        subscribe.manipulatePdf(FORM, String.format(RESULT, 3), fieldCache, "Mark Storer", "mstorer");
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
 
public class ChildFieldEvent implements PdfPCellEvent {
 
    /** A parent field to which a child field has to be added. */
    protected PdfFormField parent;
    /** The child field that has to be added */
    protected PdfFormField kid;
    /** The padding of the field inside the cell */
    protected float padding;
 
    /**
     * Creates a ChildFieldEvent.
     * @param parent the parent field
     * @param kid the child field
     * @param padding a padding
     */
    public ChildFieldEvent(PdfFormField parent, PdfFormField kid, float padding) {
        this.parent = parent;
        this.kid = kid;
        this.padding = padding;
    }
 
    /**
     * Add the child field to the parent, and sets the coordinates of the child field.
     * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell,
     *      com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[])
     */
    public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] cb) {
        try {
            parent.addKid(kid);
            kid.setWidget(new Rectangle(rect.getLeft(padding), rect.getBottom(padding),
                    rect.getRight(padding), rect.getTop(padding)),
                    PdfAnnotation.HIGHLIGHT_INVERT);
        } catch (Exception e) {
            throw new ExceptionConverter(e);
        }
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Director;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Utilities;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.html.WebColors;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.PushbuttonField;
import com.itextpdf.text.pdf.TextField;
import com.itextpdf.text.pdf.AcroFields.FieldPosition;
 
public class MovieAds {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part2/chapter08/festival.pdf";
    /** The resulting PDF: a small template for an individual ad. */
    public static final String TEMPLATE = "results/part2/chapter08/template.pdf";
    /** The source PDF file: the template for the complete ad. */
    public static final String RESOURCE = "resources/pdfs/movie_overview.pdf";
    /** Path to the movie posters */
    public static final String IMAGE = "resources/posters/%s.jpg";
    /** Field name for the poster */
    public static final String POSTER = "poster";
    /** Field name for the text */
    public static final String TEXT = "text";
    /** Field name for the year */
    public static final String YEAR = "year";
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        MovieAds movieAds = new MovieAds();
        // create a template that will be used for the ads
        movieAds.createTemplate(TEMPLATE);
        // open the connection to the database
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document();
        // step 2
        PdfSmartCopy copy = new PdfSmartCopy(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfReader reader;
        PdfStamper stamper = null;
        ByteArrayOutputStream baos = null;
        AcroFields form = null;
        int count = 0;
        for (Movie movie : PojoFactory.getMovies(connection)) {
            if (count == 0) {
                baos = new ByteArrayOutputStream();
                reader = new PdfReader(RESOURCE);
                stamper = new PdfStamper(reader, baos);
                stamper.setFormFlattening(true);
                form = stamper.getAcroFields();
            }
            count++;
            PdfReader ad = new PdfReader(movieAds.fillTemplate(TEMPLATE, movie));
            PdfImportedPage page = stamper.getImportedPage(ad, 1);
            PushbuttonField bt = form.getNewPushbuttonFromField("movie_" + count);
            bt.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
            bt.setProportionalIcon(true);
            bt.setTemplate(page);
            form.replacePushbuttonField("movie_" + count, bt.getField());
            if (count == 16) {
                stamper.close();
                reader = new PdfReader(baos.toByteArray());
                copy.addPage(copy.getImportedPage(reader, 1));
                count = 0;
            }
        }
        if (count > 0) {
            stamper.close();
            reader = new PdfReader(baos.toByteArray());
            copy.addPage(copy.getImportedPage(reader, 1));
        }
        // step 5
        document.close();
        // close the database connection
        connection.close();
    }
 
    /**
     * Create a small template that will be used for an individual ad.
     * @param filename the filename of the add
     * @throws IOException
     * @throws DocumentException
     */
    public void createTemplate(String filename) throws IOException, DocumentException {
    	// step 1
        Document document = new Document(
            new Rectangle(Utilities.millimetersToPoints(35), Utilities.millimetersToPoints(50)));
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        writer.setViewerPreferences(PdfWriter.PageLayoutSinglePage);
        // step 3
        document.open();
        // step 4
        PushbuttonField poster = new PushbuttonField(writer, new Rectangle(
                Utilities.millimetersToPoints(0), Utilities.millimetersToPoints(25),
                Utilities.millimetersToPoints(35), Utilities.millimetersToPoints(50)),
                POSTER);
        poster.setBackgroundColor(new GrayColor(0.4f));
        writer.addAnnotation(poster.getField());
        TextField movie = new TextField(writer, new Rectangle(
                Utilities.millimetersToPoints(0), Utilities.millimetersToPoints(7),
                Utilities.millimetersToPoints(35), Utilities.millimetersToPoints(25)),
                TEXT);
        movie.setOptions(TextField.MULTILINE);
        writer.addAnnotation(movie.getTextField());
        TextField screening = new TextField(writer, new Rectangle(
                Utilities.millimetersToPoints(0), Utilities.millimetersToPoints(0),
                Utilities.millimetersToPoints(35), Utilities.millimetersToPoints(7)),
                YEAR);
        screening.setAlignment(Element.ALIGN_CENTER);
        screening.setBackgroundColor(new GrayColor(0.4f));
        screening.setTextColor(GrayColor.GRAYWHITE);
        writer.addAnnotation(screening.getTextField());
        // step 5
        document.close();
    }
 
    /**
     * Fill out the small template with information about the movie.
     * @param filename the template for an individual ad
     * @param movie the movie that needs to be in the ad
     * @return a byte[] containing an individual ad
     * @throws IOException
     * @throws DocumentException
     */
    public byte[] fillTemplate(String filename, Movie movie) throws IOException, DocumentException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfReader reader = new PdfReader(filename);
        PdfStamper stamper = new PdfStamper(reader, baos);
        AcroFields form = stamper.getAcroFields();
        // change the background color of the poster and add a new icon
        BaseColor color = WebColors.getRGBColor("#" + movie.getEntry().getCategory().getColor());
        PushbuttonField bt = form.getNewPushbuttonFromField(POSTER);
        bt.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
        bt.setProportionalIcon(true);
        bt.setImage(Image.getInstance(String.format(IMAGE, movie.getImdb())));
        bt.setBackgroundColor(color);
        form.replacePushbuttonField(POSTER, bt.getField());
        // write the text using the appropriate font size
        PdfContentByte canvas = stamper.getOverContent(1);
        float size = 12;
        FieldPosition f = form.getFieldPositions(TEXT).get(0);
        while (addParagraph(createMovieParagraph(movie, size),
                canvas, f, true) && size > 6) {
            size -= 0.2;
        }
        addParagraph(createMovieParagraph(movie, size), canvas, f, false);
        // fill out the year and change the background color
        form.setFieldProperty(YEAR, "bgcolor", color, null);
        form.setField(YEAR, String.valueOf(movie.getYear()));
        // flatten the form and close the stamper
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
        return baos.toByteArray();
    }
 
    /**
     * Add a paragraph at an absolute position.
     * @param p the paragraph that needs to be added
     * @param canvas the canvas on which the paragraph needs to be drawn
     * @param f the field position
     * @param simulate does the paragraph need to be added for real?
     * @return true if the paragraph didn't fit the rectangle
     * @throws DocumentException
     */
    public boolean addParagraph(Paragraph p, PdfContentByte canvas, FieldPosition f, boolean simulate)
        throws DocumentException {
        ColumnText ct = new ColumnText(canvas);
        ct.setSimpleColumn(
            f.position.getLeft(2), f.position.getBottom(2), f.position.getRight(2), f.position.getTop());
        ct.addElement(p);
        return ColumnText.hasMoreText(ct.go(simulate));
    }
 
    /**
     * Creates a paragraph containing info about a movie
     * @param movie the Movie pojo
     * @param fontsize the font size
     * @return a Paragraph object
     */
    public Paragraph createMovieParagraph(Movie movie, float fontsize) {
        Font normal = new Font(FontFamily.HELVETICA, fontsize);
        Font bold = new Font(FontFamily.HELVETICA, fontsize, Font.BOLD);
        Font italic = new Font(FontFamily.HELVETICA, fontsize, Font.ITALIC);
        Paragraph p = new Paragraph(fontsize * 1.2f);
        p.setFont(normal);
        p.setAlignment(Element.ALIGN_JUSTIFIED);
        p.add(new Chunk(movie.getMovieTitle(), bold));
        if (movie.getOriginalTitle() != null) {
            p.add(" ");
            p.add(new Chunk(movie.getOriginalTitle(), italic));
        }
        p.add(new Chunk(String.format("; run length: %s", movie.getDuration()), normal));
        p.add(new Chunk("; directed by:", normal));
        for (Director director : movie.getDirectors()) {
            p.add(" ");
            p.add(director.getGivenName());
            p.add(", ");
            p.add(director.getName());
        }
        return p;
    }
 
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Set;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.XfaForm;
 
public class XfaMovie {
 
    /** The original PDF. */
    public static final String RESOURCE = "resources/pdfs/xfa_movie.pdf";
    /** XML making up an XFA form we want to put inside an existing PDF. */
    public static final String RESOURCEXFA = "resources/xml/xfa.xml";
    /** Shows information about a form that has an AcroForm and an XFA stream. */
    public static final String RESULTTXT1 = "results/part2/chapter08/movie_xfa.txt";
    /** Shows information about a form that has an AcroForm after the XFA stream was removed. */
    public static final String RESULTTXT2 = "results/part2/chapter08/movie_acroform.txt";
    /** The XML making up the XFA form in the original PDF */
    public static final String RESULTXML = "results/part2/chapter08/movie_xfa.xml";
    /** The XML making up the XFA form in a PDF that was filled out using iText */
    public static final String RESULTXMLFILLED = "results/part2/chapter08/movie_filled.xml";
    /** The XML data taken from an XFA form that was filled out using iText. */
    public static final String RESULTDATA = "results/part2/chapter08/movie.xml";
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/xfa_filled_1.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/xfa_filled_2.pdf";
    /** The resulting PDF. */
    public static final String RESULT3 = "results/part2/chapter08/xfa_filled_3.pdf";
 
    /**
     * Checks if a PDF containing an interactive form uses
     * AcroForm technology, XFA technology, or both.
     * Also lists the field names.
     * @param src the original PDF
     * @param dest a text file containing form info.
     * @throws IOException
     */
    public void readFieldnames(String src, String dest) throws IOException {
        PrintStream out = new PrintStream(new FileOutputStream(dest));
        PdfReader reader = new PdfReader(src);
        AcroFields form = reader.getAcroFields();
        XfaForm xfa = form.getXfa();
        out.println(xfa.isXfaPresent() ? "XFA form" : "AcroForm");
        Set<String> fields = form.getFields().keySet();
        for (String key : fields) {
            out.println(key);
        }
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Reads the XML that makes up an XFA form.
     * @param src the original PDF file
     * @param dest the resulting XML file
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws TransformerFactoryConfigurationError
     * @throws TransformerException
     */
    public void readXfa(String src, String dest)
        throws IOException, ParserConfigurationException, SAXException,
            TransformerFactoryConfigurationError, TransformerException {
        FileOutputStream os = new FileOutputStream(dest);
        PdfReader reader = new PdfReader(src);
        XfaForm xfa = new XfaForm(reader);
        Document doc = xfa.getDomDocument();
        Transformer tf = TransformerFactory.newInstance().newTransformer();
        tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tf.setOutputProperty(OutputKeys.INDENT, "yes");
        tf.transform(new DOMSource(doc), new StreamResult(os));
        reader.close();
    }
 
    /**
     * Fill out a form the "traditional way".
     * Note that not all fields are correctly filled in because of the way the form was created.
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void fillData1(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.setField("movies[0].movie[0].imdb[0]", "1075110");
        form.setField("movies[0].movie[0].duration[0]", "108");
        form.setField("movies[0].movie[0].title[0]", "The Misfortunates");
        form.setField("movies[0].movie[0].original[0]", "De helaasheid der dingen");
        form.setField("movies[0].movie[0].year[0]", "2009");
        stamper.close();
        reader.close();
    }
 
    /**
     * Fills out a form by replacing the XFA stream.
     * @param src the original PDF
     * @param xml the XML making up the new form
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     * @throws ParserConfigurationException
     * @throws SAXException
     */
    public void fillData2(String src, String xml, String dest)
        throws IOException, DocumentException, ParserConfigurationException, SAXException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        XfaForm xfa = new XfaForm(reader);
        DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
        fact.setNamespaceAware(true);
        DocumentBuilder db = fact.newDocumentBuilder();
        Document doc = db.parse(new FileInputStream(xml));
        xfa.setDomDocument(doc);
        xfa.setChanged(true);
        XfaForm.setXfa(xfa, stamper.getReader(), stamper.getWriter());
        stamper.close();
        reader.close();
    }
 
    /**
     * Reads the data from a PDF containing an XFA form.
     * @param src the original PDF
     * @param dest the data in XML format
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws TransformerFactoryConfigurationError
     * @throws TransformerException
     */
    public void readData(String src, String dest)
        throws IOException, ParserConfigurationException, SAXException,
            TransformerFactoryConfigurationError, TransformerException {
        FileOutputStream os = new FileOutputStream(dest);
        PdfReader reader = new PdfReader(src);
        XfaForm xfa = new XfaForm(reader);
        Node node = xfa.getDatasetsNode();
        NodeList list = node.getChildNodes();
        for (int i = 0; i < list.getLength(); i++) {
            if("data".equals(list.item(i).getLocalName())) {
                node = list.item(i);
                break;
            }
        }
        list = node.getChildNodes();
        for (int i = 0; i < list.getLength(); i++) {
            if("movies".equals(list.item(i).getLocalName())) {
                node = list.item(i);
                break;
            }
        }
        Transformer tf = TransformerFactory.newInstance().newTransformer();
        tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tf.setOutputProperty(OutputKeys.INDENT, "yes");
        tf.transform(new DOMSource(node), new StreamResult(os));
        reader.close();
    }
 
    /**
     * Fills out a PDF form, removing the XFA.
     * @param src
     * @param dest
     * @throws IOException
     * @throws DocumentException
     */
    public void fillData3(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        form.removeXfa();
        form.setField("movies[0].movie[0].imdb[0]", "1075110");
        form.setField("movies[0].movie[0].duration[0]", "108");
        form.setField("movies[0].movie[0].title[0]", "The Misfortunates");
        form.setField("movies[0].movie[0].original[0]", "De helaasheid der dingen");
        form.setField("movies[0].movie[0].year[0]", "2009");
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException,
        ParserConfigurationException, SAXException,
        TransformerFactoryConfigurationError, TransformerException {
        XfaMovie xfa = new XfaMovie();
        xfa.readFieldnames(RESOURCE, RESULTTXT1);
        xfa.readXfa(RESOURCE, RESULTXML);
        xfa.fillData1(RESOURCE, RESULT1);
        xfa.readXfa(RESULT1, RESULTXMLFILLED);
        xfa.fillData2(RESOURCE, RESOURCEXFA, RESULT2);
        xfa.readData(RESULT2, RESULTDATA);
        xfa.fillData3(RESOURCE, RESULT3);
        xfa.readFieldnames(RESULT3, RESULTTXT2);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.SQLException;
import java.util.List;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.XfaForm;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Country;
import com.lowagie.filmfestival.Director;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
public class XfaMovies {
 
    /** The original PDF. */
    public static final String RESOURCE = "resources/pdfs/xfa_movies.pdf";
    /** Information about the form in xfa_movies.pdf */
    public static final String RESULTTXT = "results/part2/chapter08/movies_xfa.txt";
    /** The XML data that is going to be used to fill out the XFA form. */
    public static final String XMLDATA = "results/part2/chapter08/movies.xml";
    /** The resulting PDF. */
    public static final String RESULT = "results/part2/chapter08/xfa_filled_in.pdf";
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param xml the XML data that needs to be added to the XFA form
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String xml, String dest)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader,
                new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        XfaForm xfa = form.getXfa();
        xfa.fillXfaForm(new FileInputStream(xml));
        stamper.close();
        reader.close();
    }
 
    /**
     * Creates an XML file containing data about movies.
     * @param dest the path to the resulting XML file
     * @throws IOException
     * @throws SQLException
     */
    public void createXML(String dest) throws IOException, SQLException {
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(dest), "UTF-8");
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        List<Movie> movies = PojoFactory.getMovies(connection);
        out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
        out.write("<movies>\n");
        for (Movie movie : movies) {
            out.write(getXml(movie));
        }
        out.write("</movies>");
        out.flush();
        out.close();
        connection.close();
    }
 
    /**
     * Creates an XML snippet containing information about a movie.
     * @param movie the Movie pojo
     * @return an XML snippet 
     */
    public String getXml(Movie movie) {
        StringBuffer buf = new StringBuffer();
        buf.append("<movie duration=\"");
        buf.append(movie.getDuration());
        buf.append("\" imdb=\"");
        buf.append(movie.getImdb());
        buf.append("\" year=\"");
        buf.append(movie.getYear());
        buf.append("\">");
        buf.append("<title>");
        buf.append(movie.getMovieTitle());
        buf.append("</title>");
        if (movie.getOriginalTitle() != null) {
            buf.append("<original>");
            buf.append(movie.getOriginalTitle());
            buf.append("</original>");
        }
        buf.append("<directors>");
        for (Director director : movie.getDirectors()) {
            buf.append("<director>");
            buf.append(director.getName());
            buf.append(", ");
            buf.append(director.getGivenName());
            buf.append("</director>");
        }
        buf.append("</directors>");
        buf.append("<countries>");
        for (Country country : movie.getCountries()) {
            buf.append("<country>");
            buf.append(country.getCountry());
            buf.append("</country>");
        }
        buf.append("</countries>");
        buf.append("</movie>\n");
        return buf.toString();
    }
 
    /**
     * Main method
     * @param args no arguments needed
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, SQLException, DocumentException {
        new XfaMovie().readFieldnames(RESOURCE, RESULTTXT);
        XfaMovies xfa = new XfaMovies();
        xfa.createXML(XMLDATA);
        xfa.manipulatePdf(RESOURCE, XMLDATA, RESULT);
    }
}
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter08;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
 
import org.xml.sax.SAXException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
public class ReaderEnabledForm {
 
    /** The original PDF. */
    public static final String RESOURCE = "resources/pdfs/xfa_enabled.pdf";
    /** The resulting PDF. */
    public static final String RESULT1 = "results/part2/chapter08/xfa_broken.pdf";
    /** The resulting PDF. */
    public static final String RESULT2 = "results/part2/chapter08/xfa_removed.pdf";
    /** The resulting PDF. */
    public static final String RESULT3 = "results/part2/chapter08/xfa_preserved.pdf";
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest, boolean remove, boolean preserve)
        throws IOException, DocumentException {
        // create the reader
    	PdfReader reader = new PdfReader(src);
        // remove the usage rights (or not)
        if (remove)
            reader.removeUsageRights();
        // create the stamper
        PdfStamper stamper;
        // preserve the reader enabling by creating a PDF in append mode (or not)
        if (preserve) {
            stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true);
        } else {
            stamper = new PdfStamper(reader, new FileOutputStream(dest));
        }
        // fill out the fields
        AcroFields form = stamper.getAcroFields();
        form.setField("movie[0].#subform[0].title[0]", "The Misfortunates");
        form.setField("movie[0].#subform[0].original[0]", "De helaasheid der dingen");
        form.setField("movie[0].#subform[0].duration[0]", "108");
        form.setField("movie[0].#subform[0].year[0]", "2009");
        // close the stamper
        stamper.close();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws TransformerFactoryConfigurationError
     * @throws TransformerException
     * @throws DocumentException
     */
    public static void main(String[] args) throws IOException, DocumentException,
        ParserConfigurationException, SAXException,
        TransformerFactoryConfigurationError, TransformerException {
        ReaderEnabledForm form = new ReaderEnabledForm();
        form.manipulatePdf(RESOURCE, RESULT1, false, false);
        form.manipulatePdf(RESOURCE, RESULT2, true, false);
        form.manipulatePdf(RESOURCE, RESULT3, false, true);
    }
}
C# port: 
File nameRaw URLUpdated
Buttons.csButtons.cs2015-10-10 3:01 pm
RadioButtons.csRadioButtons.cs2015-10-10 3:01 pm
ReplaceIcon.csReplaceIcon.cs2015-10-10 3:01 pm
TextFields.csTextFields.cs2015-10-10 3:01 pm
TextFieldFonts.csTextFieldFonts.cs2015-10-10 3:01 pm
TextFieldActions.csTextFieldActions.cs2015-10-10 3:01 pm
ChoiceFields.csChoiceFields.cs2015-10-10 3:01 pm
Subscribe.csSubscribe.cs2015-10-10 3:01 pm
ChildFieldEvent.csChildFieldEvent.cs2015-10-10 3:01 pm
MovieAds.csMovieAds.cs2015-10-10 3:01 pm
XfaMovie.csXfaMovie.cs2015-10-10 3:01 pm
XfaMovies.csXfaMovies.cs2015-10-10 3:01 pm
ReaderEnabledForm.csReaderEnabledForm.cs2015-10-10 3:01 pm