Using forms for reporting

Tags: merge documentsformsiText 5PdfCopymerge fieldsPdfSmartCopy

A series of examples that allow you to create reports using forms.

These examples were used to answer questions such as:

Files: 
package sandbox.acroforms.reporting;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import sandbox.WrapToTest;
 
@WrapToTest(compareRenders = true)
public class FillForm {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/reporting/california.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FillForm().manipulatePdf(SRC, DEST);
    }
    public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader,
                new FileOutputStream(dest));
        AcroFields fields = stamper.getAcroFields();
        fields.setField("name", "CALIFORNIA");
        fields.setField("abbr", "CA");
        fields.setField("capital", "Sacramento");
        fields.setField("city", "Los Angeles");
        fields.setField("population", "36,961,664");
        fields.setField("surface", "163,707");
        fields.setField("timezone1", "PT (UTC-8)");
        fields.setField("timezone2", "-");
        fields.setField("dst", "YES");
        stamper.close();
        reader.close();
    }
}
package sandbox.acroforms.reporting;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import sandbox.WrapToTest;
 
@WrapToTest(compareRenders = true)
public class FlattenForm {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/reporting/california2.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FlattenForm().manipulatePdf(SRC, DEST);
    }
    public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader,
                new FileOutputStream(dest));
        AcroFields fields = stamper.getAcroFields();
        fields.setField("name", "CALIFORNIA");
        fields.setField("abbr", "CA");
        fields.setField("capital", "Sacramento");
        fields.setField("city", "Los Angeles");
        fields.setField("population", "36,961,664");
        fields.setField("surface", "163,707");
        fields.setField("timezone1", "PT (UTC-8)");
        fields.setField("timezone2", "-");
        fields.setField("dst", "YES");
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
    }
}
package sandbox.acroforms.reporting;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
 
import sandbox.WrapToTest;
 
@WrapToTest(compareRenders = true)
public class FillFlattenMerge1 {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/reporting/united_states_1.pdf";
    public static final String DATA = "resources/data/united_states.csv";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FillFlattenMerge1().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
        Document document = new Document();
        // Using PdfCopy isn't a good idea in this use case.
        // Take a look at FillFlattenMerge2 to find out how to do it right!
        PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest));
        document.open();
        ByteArrayOutputStream baos;
        PdfReader reader;
        PdfStamper stamper;
        AcroFields fields;
        StringTokenizer tokenizer;
        BufferedReader br = new BufferedReader(new FileReader(DATA));
        String line = br.readLine();
        while ((line = br.readLine()) != null) {
            // create a PDF in memory
            baos = new ByteArrayOutputStream();
            reader = new PdfReader(SRC);
            stamper = new PdfStamper(reader, baos);
            fields = stamper.getAcroFields();
            tokenizer = new StringTokenizer(line, ";");
            fields.setField("name", tokenizer.nextToken());
            fields.setField("abbr", tokenizer.nextToken());
            fields.setField("capital", tokenizer.nextToken());
            fields.setField("city", tokenizer.nextToken());
            fields.setField("population", tokenizer.nextToken());
            fields.setField("surface", tokenizer.nextToken());
            fields.setField("timezone1", tokenizer.nextToken());
            fields.setField("timezone2", tokenizer.nextToken());
            fields.setField("dst", tokenizer.nextToken());
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            // add the PDF to PdfCopy
            reader = new PdfReader(baos.toByteArray());
            copy.addDocument(reader);
            reader.close();
        }
        br.close();
        document.close();
    }
}
package sandbox.acroforms.reporting;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
 
import sandbox.WrapToTest;
 
@WrapToTest(compareRenders = true)
public class FillFlattenMerge2 {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/reporting/united_states_2.pdf";
    public static final String DATA = "resources/data/united_states.csv";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FillFlattenMerge2().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
        Document document = new Document();
        PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
        document.open();
        ByteArrayOutputStream baos;
        PdfReader reader;
        PdfStamper stamper;
        AcroFields fields;
        StringTokenizer tokenizer;
        BufferedReader br = new BufferedReader(new FileReader(DATA));
        String line = br.readLine();
        while ((line = br.readLine()) != null) {
            // create a PDF in memory
            baos = new ByteArrayOutputStream();
            reader = new PdfReader(SRC);
            stamper = new PdfStamper(reader, baos);
            fields = stamper.getAcroFields();
            tokenizer = new StringTokenizer(line, ";");
            fields.setField("name", tokenizer.nextToken());
            fields.setField("abbr", tokenizer.nextToken());
            fields.setField("capital", tokenizer.nextToken());
            fields.setField("city", tokenizer.nextToken());
            fields.setField("population", tokenizer.nextToken());
            fields.setField("surface", tokenizer.nextToken());
            fields.setField("timezone1", tokenizer.nextToken());
            fields.setField("timezone2", tokenizer.nextToken());
            fields.setField("dst", tokenizer.nextToken());
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            // add the PDF to PdfCopy
            reader = new PdfReader(baos.toByteArray());
            copy.addDocument(reader);
            reader.close();
        }
        br.close();
        document.close();
    }
}
package sandbox.acroforms.reporting;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
 
import sandbox.WrapToTest;
 
@WrapToTest(compareRenders = true)
public class FillFlattenMerge3 {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/reporting/united_states_3.pdf";
    public static final String DATA = "resources/data/united_states.csv";
    public static final String[] FIELDS = {
        "name", "abbr", "capital", "city", "population", "surface", "timezone1", "timezone2", "dst"
    };
    public static final Font FONT = new Font(FontFamily.HELVETICA, 10);
 
    protected Map<String, Rectangle> positions;
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FillFlattenMerge3().manipulatePdf(SRC, DEST);
    }
 
    public class Background extends PdfPageEventHelper {
 
        PdfImportedPage background;
 
        public Background(PdfImportedPage background) {
            this.background = background;
        }
 
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            PdfContentByte cb = writer.getDirectContentUnder();
            cb.addTemplate(background, 0, 0);
            ColumnText.showTextAligned(cb, Element.ALIGN_RIGHT, new Phrase("page " + writer.getPageNumber()), 550, 800, 0);
        }
 
    }
 
    public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
        PdfReader reader = new PdfReader(src);
        AcroFields form = reader.getAcroFields();
        positions = new HashMap<String, Rectangle>();
        Rectangle rectangle;
        Map<String, AcroFields.Item> fields = form.getFields();
        for (String name : fields.keySet()) {
            rectangle = form.getFieldPositions(name).get(0).position;
            positions.put(name, rectangle);
        }
 
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        writer.setPageEvent(new Background(writer.getImportedPage(reader, 1)));
        document.open();
 
        PdfContentByte cb = writer.getDirectContent();
        StringTokenizer tokenizer;
        BufferedReader br = new BufferedReader(new FileReader(DATA));
        String line = br.readLine();
        while ((line = br.readLine()) != null) {
            int i = 0;
            tokenizer = new StringTokenizer(line, ";");
            while (tokenizer.hasMoreTokens()) {
                process(cb, FIELDS[i++], tokenizer.nextToken());
            }
            document.newPage();
        }
        br.close();
        document.close();
 
        reader.close();
    }
 
    protected void process(PdfContentByte cb, String name, String value) throws DocumentException {
        Rectangle rect = positions.get(name);
        Phrase p = new Phrase(value, FONT);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
                p, rect.getLeft() + 2, rect.getBottom() + 2, 0);
    }
}
package sandbox.acroforms;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class MergeForms {
 
    public static final String SRC1 = "resources/pdfs/subscribe.pdf";
    public static final String SRC2 = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/merged_form.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new MergeForms().createPdf(DEST);
    }
 
    public void createPdf(String filename, PdfReader[] readers) throws IOException, DocumentException {
        Document document = new Document();
        PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
        copy.setMergeFields();
        document.open();
        for (PdfReader reader : readers) {
            copy.addDocument(reader);
        }
        document.close();
        for (PdfReader reader : readers) {
            reader.close();
        }
    }
 
    public void createPdf(String filename) throws IOException, DocumentException {
        PdfReader[] readers = {
            new PdfReader(getFile1()),
            new PdfReader(getFile2())
        };
        createPdf(filename, readers);
    }
 
    public String getFile1() { return SRC1; }
    public String getFile2() { return SRC2; }
}
package sandbox.acroforms;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import sandbox.WrapToTest;
 
@WrapToTest
public class MergeForms2 {
 
    public static final String SRC = "resources/pdfs/state.pdf";
    public static final String DEST = "results/acroforms/merged_form2.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new MergeForms2().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        Document document = new Document();
        PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
        copy.setMergeFields();
        document.open();
        List<PdfReader> readers = new ArrayList<PdfReader>();
        for (int i = 0; i < 3; ) {
            PdfReader reader = new PdfReader(renameFields(src, ++i));
            readers.add(reader);
            copy.addDocument(reader);
        }
        document.close();
        for (PdfReader reader : readers) {
            reader.close();
        }
    }
 
    public byte[] renameFields(String src, int i) throws IOException, DocumentException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, baos);
        AcroFields form = stamper.getAcroFields();
        Set<String> keys = new HashSet<String>(form.getFields().keySet());
        for (String key : keys) {
            form.renameField(key, String.format("%s_%d", key, i));
        }
        stamper.close();
        reader.close();
        return baos.toByteArray();
    }
}
File nameRaw URLUpdated
FillForm.javaFillForm.java2015-10-30 6:21 pm
FlattenForm.javaFlattenForm.java2015-10-30 6:21 pm
FillFlattenMerge1.javaFillFlattenMerge1.java2015-10-30 6:21 pm
FillFlattenMerge2.javaFillFlattenMerge2.java2015-10-30 6:21 pm
FillFlattenMerge3.javaFillFlattenMerge3.java2015-10-30 6:21 pm
MergeForms.javaMergeForms.java2015-11-06 12:27 pm
MergeForms2.javaMergeForms2.java2015-11-06 12:27 pm
Resources: 
File nameRaw URLUpdated
state.pdfstate.pdf2015-10-30 6:23 pm
subscribe.pdfsubscribe.pdf2015-11-06 12:28 pm
united_states.csvunited_states.csv2015-10-24 12:06 am