itext

55
Creating PDFs with Java

Upload: kaviarasu

Post on 12-Nov-2014

1.236 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: itext

Creating PDFs with Java

Page 2: itext

What we will cover

• Using the API to create PDFs from scratch.• Writing to Acrobat forms.• Building a sample application. • Deploying PDFs in a Web application.

Page 3: itext

What is iText?

• Java library for creating and manipulating PDFs

• Open source• Free

Page 4: itext

iText Features

• Create PDFs• Populate PDF forms• Tables• JPEG, GIF and PNG images• PDF encryption• Headers, footers• Barcodes

Page 5: itext

Key Classes

• Document - The document to write to.• PdfWriter - A writer for the document.

Creates a PDF representation of every element in the document.

Page 6: itext

Example 1 (Hello World)import com.lowagie.text.*;import com.lowagie.text.pdf.PdfWriter;public class HelloWorld{ public static void main(String[] args) {

// step 1: creation of a document-object Document document = new Document(); try { // step 2: we create a writer that listens to the document and directs // a PDF-stream to a file PdfWriter.getInstance(document,

new FileOutputStream("c:\\itext\\Hello.pdf")); // step 3: we open the document document.open(); // step 4: we add a paragraph to the document document.add(new Paragraph("Hello World")); } catch(Exception ex) {System.err.println(ex.getMessage());} // step 5: we close the document

document.close(); }}

Page 7: itext

Output

Page 8: itext

Example 2 (Image )import com.lowagie.text.*;import com.lowagie.text.pdf.*;

public class ImageTest { public static void main(String[] args) { Document document = new Document(PageSize.A4, 50, 50, 50, 50); try { PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("c:\\itext\\imageTest.pdf")); document.open(); Image img = Image.getInstance("c:\\itext\\linux.gif"); document.add(img); img.scalePercent(20); img.setRotationDegrees(190); img.setAlignment(Image.RIGHT); document.add(img); img.scalePercent(25); img.setRotationDegrees(0); img.setAbsolutePosition(171, 250); document.add(img); document.close(); }catch (Exception de) {de.printStackTrace();} }}

Page 9: itext
Page 10: itext

Example 3 (Table)import java.io.*;import java.awt.Point;

import com.lowagie.text.*;import com.lowagie.text.pdf.PdfWriter;

public class Chap0503 { public static void main(String[] args) {

// step 1: creation of a document-object Document document = new Document(); try { // step 2: // we create a writer that listens to the document // and directs a PDF-stream to a file PdfWriter.getInstance(document, new FileOutputStream("Chap0503.pdf")); // step 3: we open the document document.open();

Page 11: itext

Example 3 (cont)

// step 4: we create a table and add it to the document Table aTable = new Table(4,4); // 4 rows, 4 columns aTable.setAutoFillEmptyCells(true); aTable.addCell("2.2", new Point(2,2)); aTable.addCell("3.3", new Point(3,3)); aTable.addCell("2.1", new Point(2,1)); aTable.addCell("1.3", new Point(1,3)); aTable.addCell("5.2", new Point(5,2)); aTable.addCell("6.1", new Point(6,1)); aTable.addCell("5.0", new Point(5,0)); document.add(aTable); } catch(Exception ex) { System.err.println(de.getMessage());}

// step 5: we close the document document.close(); }}

Page 12: itext
Page 13: itext

Acrobat Forms

• Why use Acrobat forms?• Forms are editable• Forms can be written to or read from using

iText API

Page 14: itext

Typical Form

Page 15: itext

Acrobat Forms

• Why use Acrobat forms?• Forms are editable• Forms can be written to or read from using

iText API

Page 16: itext

Editable Form

Page 17: itext

Acrobat Forms

• Why use Acrobat forms?• Forms are editable• Form fields can be written to or read using

iText API

Page 18: itext

Underlying Form Fields

Page 19: itext

Talking to a PDF

Page 20: itext

Key Classes

• PDFReader - Reads a PDF from a file, byte array, or URL.

• PdfStamper - Lets you add things to an existing PDF.

• AcroFields - Contains information on the form fields. Can also remove or rename fields and set field values.

Page 21: itext

How to get the Fieldnames

SomeForm.pdf

PDFReader

PDFStamper

AcroForms

set/get fields

Page 22: itext

Example 5(Set, Get, Rename Fields)

import java.io.*;import java.util.*;import com.lowagie.text.pdf.*;

public class SetupExample { public void processFields(){ try{ //Reads a PDF document named "f1040.pdf". PdfReader reader = new PdfReader("f1040.pdf"); PdfStamper stamp = new PdfStamper(reader, new FileOutputStream("Altered1040.pdf")); //rename the fields AcroFields form = stamp.getAcroFields(); form.renameField("f1-4", "firstName"); form.renameField("f1-5", "lastName"); form.renameField("f1-11", "ssn1"); form.renameField("f1-12", "ssn2"); form.renameField("f1-13", "ssn3"); form.setField("f1-6", ”spouse first name");

String spouseLastName = form.getField("f1-7"); //Writes the result to a file named "Altered1040.pdf" stamp.close();

Page 23: itext
Page 24: itext

Creating a Wrapper Class

• Why a wrapper class?• We need to know the document name and

the key value pairs.• I wrote the following utility to generate a

wrapper class for a PDF form.

Page 25: itext

Code Generation Toolimport java.io.*;import java.util.*;import com.lowagie.text.pdf.*;

public class PdfFormGenerator {

private String className; private String formName; private StringBuffer generatedClass = new StringBuffer(); public PdfFormGenerator(String formName, String className){ this.formName = formName; this.className = className; try{ //get the field names PdfReader reader = new PdfReader(formName); PdfStamper stamp = new PdfStamper(reader, new ByteArrayOutputStream()); AcroFields form = stamp.getAcroFields(); HashMap formFields = form.getFields();

Page 26: itext

Code Generation Tool (cont) // generate a class Set formFieldNames = new TreeSet(formFields.keySet()); Iterator nameIterator = formFieldNames.iterator(); generatedClass.append(clsStart()); // Top of class code generatedClass.append(construct()); StringBuffer methods = new StringBuffer(); String initMembers = new String(); // loop through all fieldnames in the pdf template while(nameIterator.hasNext()){ String pdfFieldName = (String) nameIterator.next(); String javaName = pdfFieldName; //convert irs fieldnames into something java can use in a method name if(javaName.indexOf('-')>0){ javaName = javaName.replaceAll("-", "Field"); } methods.append(setMethod(javaName, pdfFieldName)); initMembers += initMember(javaName); } methods.append("\n public HashMap getData() {\n return data;\n }\n"); methods.append("\n public String getPdfTemplateName() {\n return pdfTemplateName;\n }\n"); methods.append("\n public void setPdfTemplateName(String pdfTemplateName) {\n

Page 27: itext

Code Generation Tool (cont) generatedClass.append(methods); generatedClass.append("}"); }catch(Exception ex){ex.printStackTrace(); }

clsStart(); } private String clsStart() {

String s ="\n\nimport java.util.*;"; s+="\n\npublic class " + className + " implements PdfForm{"; s+="\n\n private HashMap data = new HashMap();"; s+="\n private String pdfTemplateName = \""+formName+"\";\n";

return s; } private String construct() {

String s = "\n public " + className + "() {\n }"; return s;

} public String initMember(String fieldName) {

String s = "\n " + fieldName + " = new String();"; return s;

}

Page 28: itext

Code Generation Tool (cont) public String getMethod(String javaName, String value) {

String s = new String(); s = headerComment("Returns the value of "+value); s += "\n public String get"+ cap(javaName)+"() {"; s += "\n return (String)data.get(\""+value + "\");\n }"; return s;

} private String cap(String s) {

return s.substring(0,1).toUpperCase() + s.substring(1); } private String headerComment(String text) {

return " \n /**\n *"+text+"\n */"; } public String setMethod(String javaName, String value) {

String z = new String(); z = headerComment("Sets the value of "+value); z += "\n public void set"+ cap(javaName) +"(String value) {";

z += "\n data.put(\""+value+"\", value);\n }\n"; return z;

}

Page 29: itext

Code Generation Tool (cont) public void writeToFiles() throws Exception {

FileWriter fw = new FileWriter(className + ".java"); fw.write(generatedClass.toString()); fw.close(); return;

}

public static void main(String[] args){ try{ PdfFormGenerator gen = new PdfFormGenerator(args[0], args[1]); gen.writeToFiles(); }catch(Exception ex){ ex.printStackTrace(); } }}

Page 30: itext

The Wrapper Classes Implement

Public interface PdfForm { public HashMap getData(); public String getPdfTemplateName();}

Page 31: itext

Sample Generated ClassImport java.util.*;public class Irs1040 implements PdfForm{ private HashMap data = new HashMap(); private String pdfTemplateName = "Altered1040.pdf";

public Irs1040() {} public void setFirstName(String value) { data.put("firstName", value); } public void setLastName(String value) { data.put("lastName", value); }

Page 32: itext

A First Full Example

• Write the data to the wrapper classes• Use the original PDF forms as templates• Use PdfStamper to get the PDF fields• Set the field values in the form.• Set form flattening to make the data fields

no longer editable.

Page 33: itext

Populating the PDFSomeForm.pdf

PDFReader

PDFStamper

AcroForms

set fields

Wrapper

Key/Value

Page 34: itext

Example 6 (Writing to a Form)import java.io.*;import java.util.*;

import com.lowagie.text.*;import com.lowagie.text.pdf.*;

public class FormWriter { public FormWriter(PdfForm pdfForm, String outputPDF){ try{ String templateName = pdfForm.getPdfTemplateName(); PdfReader reader = new PdfReader(templateName); PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outputPDF)); AcroFields acroFields = stamp.getAcroFields(); //This is our data Map valueMap = pdfForm.getData(); //get a list of fields in the pdf HashMap formFields = acroFields.getFields(); Set formFieldNames = formFields.keySet(); Iterator nameIterator = formFieldNames.iterator();

Page 35: itext

Example 6 (cont.) //loops through all field names in the pdf template while(nameIterator.hasNext()){ // pdf template field name String fieldName = (String) nameIterator.next(); // value for field, if any Object value = valueMap.get(fieldName);

// set our value in the form if(value != null){ String fieldStringValue = (String) value; acroFields.setField(fieldName, fieldStringValue); } } //gets rid of editable fields, makes them part of the document stamp.setFormFlattening(true); //Closes the document. No more content can be written stamp.close();

} catch (Exception ex) {ex.printStackTrace();} }

Page 36: itext

Example 6 (cont.) public static void main(String[] args) { Irs1040SchedDCont irs1040SD = new Irs1040SchedDCont(); irs1040SD.setName("Test"); irs1040SD.setSsn1("999"); irs1040SD.setSsn2("11"); irs1040SD.setSsn3("1234"); new FormWriter(irs1040SD, "C:\\itext\\1040Out.pdf"); }}

Page 37: itext

Output

Page 38: itext

Merging PDFs• iText can merge many PDFs into a single

document.• Conversely, individual pages can be

selected from a document to create new PDFs

• Key API classes are:– PDFCopy - Makes copies of PDF Documents– PdfImportedPage - Selects a page out of a PDF

Page 39: itext

Merging PDFsImport java.io.*;import java.util.*;import java.net.*;

import com.lowagie.text.*;import com.lowagie.text.pdf.*;

public class PdfProcessor { public PdfProcessor(Vector pdfForms, OutputStream outStream){ try{ // this is a blank document we will be adding pages to Document mergedPDF = new Document(); // makes copies of PDF documents. PdfCopy writer = new PdfCopy(mergedPDF, outStream); // open the document so we can add content mergedPDF.open();

Iterator iterator = pdfForms.iterator();

Page 40: itext

Merging PDFs // do this for each form

while(iterator.hasNext()){ Object object = iterator.next(); PdfForm pdfForm = (PdfForm)object; // get the name of the pdf template String templateName = pdfForm.getPdfTemplateName(); // get our data Map valueMap = pdfForm.getData();

PdfReader singlePDF = new PdfReader(templateName); ByteArrayOutputStream pdfStream = new ByteArrayOutputStream(); PdfStamper stamp = new PdfStamper(singlePDF, pdfStream);

// Acrofields can query and change fields in existing documents AcroFields form = stamp.getAcroFields(); // get a list of fields in the pdf HashMap formFields = form.getFields(); Set formFieldNames = formFields.keySet(); Iterator nameIterator = formFieldNames.iterator();

Page 41: itext

Merging PDFs // loops through all field names in the PDF template

while(nameIterator.hasNext()){ //pdf template field name String fieldName = (String) nameIterator.next(); //value for field, if any Object value = valueMap.get(fieldName);

if(value != null){ String fieldStringValue = (String) value; form.setField(fieldName, fieldStringValue); } } //gets rid of editable fields, makes them part of the document stamp.setFormFlattening(true);

//Closes the document. stamp.close();

PdfReader completedPDF = new PdfReader(pdfStream.toByteArray()); int numPages = completedPDF.getNumberOfPages();

Page 42: itext

Merging PDFs // copy each page of the document

for (int i = 0; i < numPages; ++i){ // Gets the specified page from the input document PdfImportedPage page = writer.getImportedPage(completedPDF, i+1); // Add an imported page to our output writer.addPage(page); }

PRAcroForm completedform = completedPDF.getAcroForm(); if (completedform != null){ // Copy the acroform for an input document. writer.copyAcroForm(completedPDF); } } // close document (and output stream). mergedPDF.close();

} catch (Exception ex) { ex.printStackTrace();

} }}

Page 43: itext

Build a Sample Application

• Simulate a tax application that uses multiple pdf’s, writes data, and produces a single non-editable pdf using the code we have shown.

Page 44: itext

Example 7 (Tax application)import java.util.*;

import java.io.*;

public class TaxTool {

private String firstName = new String();

private String lastName = new String();

private String ssn1 = new String();

private String ssn2 = new String();

private String ssn3 = new String();

Vector forms = new Vector();

public Vector getFormData(){

Irs1040 irs1040 = new Irs1040();

irs1040.setFirstName(firstName);

irs1040.setLastName(lastName);

irs1040.setSsn1(ssn1);

irs1040.setSsn2(ssn2);

irs1040.setSsn3(ssn3);

forms.add(irs1040);

Page 45: itext

Example 7 (cont) Irs1040SchedD irs1040SD = new Irs1040SchedD();

irs1040SD.setName(firstName+" "+lastName);

irs1040SD.setSsn1(ssn1);

irs1040SD.setSsn2(ssn2);

irs1040SD.setSsn3(ssn3);

forms.add(irs1040SD);

Irs1040SchedDCont irs1040SD1 = new Irs1040SchedDCont();

irs1040SD1.setName(firstName+" "+lastName);

irs1040SD1.setSsn1(ssn1);

irs1040SD1.setSsn2(ssn2);

irs1040SD1.setSsn3(ssn3);

irs1040SD1.setNamePage2(firstName+" "+lastName);

irs1040SD1.setSsn1Page2(ssn1);

irs1040SD1.setSsn2Page2(ssn2);

irs1040SD1.setSsn3Page2(ssn3);

forms.add(irs1040SD1);

Page 46: itext

Example 7 (cont) Irs1040SchedE irs1040SE = new Irs1040SchedE();

irs1040SE.setName(firstName+" "+lastName);

irs1040SE.setSsn1(ssn1);

irs1040SE.setSsn2(ssn2);

irs1040SE.setSsn3(ssn3);

irs1040SE.setNamePage2(firstName+" "+lastName);

irs1040SE.setSsn1Page2(ssn1);

irs1040SE.setSsn2Page2(ssn2);

irs1040SE.setSsn3Page2(ssn3);

forms.add(irs1040SE);

Irs1040SchedEIC irs1040SEI = new Irs1040SchedEIC();

irs1040SEI.setName(firstName+" "+lastName);

irs1040SEI.setSsn1(ssn1);

irs1040SEI.setSsn2(ssn2);

irs1040SEI.setSsn3(ssn3);

forms.add(irs1040SEI);

return forms;

}

Page 47: itext

Example 7 (cont)

public static void main(String[] args){

TaxTool taxTool = new TaxTool();

taxTool.setFirstName("Mark");

taxTool.setLastName("Stark");

taxTool.setSsn1("123");

taxTool.setSsn2("45");

taxTool.setSsn3("6789");

Vector forms = taxTool.getFormData();

try{

PdfProcessor processor = new PdfProcessor(forms,

new FileOutputStream("C:\\itext\\myResults", false));

}catch(FileNotFoundException ex){

ex.printStackTrace();

}

}

Page 48: itext

Output Demo

Page 49: itext

PDFs in a Web Application

• Create the document using the iText API and a ByteArrayOutputStream

• Set HTTP response headers• Get ServletOutputStream object • Write document bytes to the

ServletOutputStream• Flush the ServletOutputStream

Page 50: itext

Example 8 (Servlet Code)import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class ItextExampleServlet extends HttpServlet {

protected void processRequest(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

//get data from the request page

String firstName = request.getParameter("firstName");

String lastName = request.getParameter("lastName");

String ssn1 = request.getParameter("ssn1");

String ssn2 = request.getParameter("ssn2");

String ssn3 = request.getParameter("ssn3");

Page 51: itext

Example 8 (cont)

//populate forms with the data

TaxTool taxTool = new TaxTool();

taxTool.setFirstName(firstName);

taxTool.setLastName(lastName);

taxTool.setSsn1(ssn1);

taxTool.setSsn2(ssn2);

taxTool.setSsn3(ssn3);

Vector forms = taxTool.getFormData();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

//merge the forms into one document

PdfProcessor processor = new PdfProcessor(forms, baos);

Page 52: itext

Example 8 (cont)

//let the browser know it is a pdf

response.setContentType("application/pdf");

//Set the content-length header to the number of bytes in the PDF file.

response.setContentLength(baos.size());

//let the browser know how to display it and what to name the file

response.setHeader("Content-disposition",

" inline; filename=yourTaxes.pdf");

ServletOutputStream sos = response.getOutputStream();

baos.writeTo(sos);

//send all bytes to the client.

sos.flush();

}

Page 53: itext

Demonstration

Page 54: itext

Further Information

• iText lead developers: Bruno Lowagie, Paulo Soares

• Website: http://www.lowagie.com/iText• Beta: http://itextpdf.sourceforge.net/

Page 55: itext

Questions?