PDF and Excel downloads from a Web Application using POI and iText

This is a web project that employs two servlets, ExcelCreator and PdfCreator.java. In addition to the normal jars associated with servlets(most of these can be found in tomcat lib folders), we need two extra jars for our purposes. I have used itext_1.5.4.jar and poi-2.5.1.jar. Both these jars need to be on the classpath of the project and web-inf lib of the war. itext makes pdf creation simple while poi is associated with excel creation.
Java code used in the application follows:

ExcelCreator.java which is a servlet that creates the Excel file.


package com.mattiz.excelPdf;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelCreator extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		ClassVO classVO = new PopulationHandler().populateData();
		res.setContentType("application/vnd.ms-excel");
		res.setHeader("Content-disposition", "attachment; filename="
				+ "SchoolReport.xls");
		HSSFWorkbook workBook = new HSSFWorkbook();
		workBook = createHSSFSheet(classVO, workBook);
		try {
			OutputStream out = res.getOutputStream();
			workBook.write(out);
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private HSSFWorkbook createHSSFSheet(ClassVO classVO, HSSFWorkbook workBook) {
		HSSFSheet sheet = workBook.createSheet("School Report");
		int rowNum = 0;
		HSSFRow rowHeader = sheet.createRow(rowNum++);
		rowHeader.createCell((short) 0).setCellValue("Class Name");
		rowHeader.createCell((short) 1).setCellValue("Age Group");
		HSSFRow rowContent = sheet.createRow(rowNum++);
		rowContent.createCell((short) 0).setCellValue(classVO.getClassName());
		rowContent.createCell((short) 1).setCellValue(classVO.getAgeGroup());
		HSSFRow blankRow1 = sheet.createRow(rowNum++);
		blankRow1.createCell((short) 0).setCellValue("");
		HSSFRow innerRowHeader = sheet.createRow(rowNum++);
		innerRowHeader.createCell((short) 0).setCellValue("First Name");
		innerRowHeader.createCell((short) 1).setCellValue("Last Name");
		innerRowHeader.createCell((short) 2).setCellValue("Date Of Birth");
		innerRowHeader.createCell((short) 3).setCellValue("Grade");
		innerRowHeader.createCell((short) 4).setCellValue("Physics");
		innerRowHeader.createCell((short) 5).setCellValue("Chemistry");
		innerRowHeader.createCell((short) 6).setCellValue("Maths");
		innerRowHeader.createCell((short) 7).setCellValue("Biology");
		long phyMarks = 0;
		long chemMarks = 0;
		long mathMarks = 0;
		long bioMarks = 0;
		List<StudentVO> studentDetailsList = classVO.getStudentDetails();
		for (int j = 0; j < studentDetailsList.size(); j++) {
			StudentVO studentVO = studentDetailsList.get(j);
			// create the row data
			HSSFRow innerRowContent = sheet.createRow(rowNum++);
			innerRowContent.createCell((short) 0).setCellValue(
					studentVO.getFirstName());
			innerRowContent.createCell((short) 1).setCellValue(
					studentVO.getLastName());
			innerRowContent.createCell((short) 2).setCellValue(
					studentVO.getDateOfBirth());
			innerRowContent.createCell((short) 3).setCellValue(
					studentVO.getGrade());
			innerRowContent.createCell((short) 4).setCellValue(
					studentVO.getPhysicsMarks());
			phyMarks += studentVO.getPhysicsMarks();
			innerRowContent.createCell((short) 5).setCellValue(
					studentVO.getChemistryMarks());
			chemMarks += studentVO.getChemistryMarks();
			innerRowContent.createCell((short) 6).setCellValue(
					studentVO.getMathsMarks());
			mathMarks += studentVO.getMathsMarks();
			innerRowContent.createCell((short) 7).setCellValue(
					studentVO.getBiologyMarks());
			bioMarks += studentVO.getBiologyMarks();
		}
		HSSFRow blankRow2 = sheet.createRow(rowNum++);
		blankRow2.createCell((short) 0).setCellValue("");
		HSSFRow outerRowHeader = sheet.createRow(rowNum++);
		outerRowHeader.createCell((short) 0).setCellValue(
				"Average Marks In Physics");
		outerRowHeader.createCell((short) 1).setCellValue(
				"Average Marks In Chemistry");
		outerRowHeader.createCell((short) 2).setCellValue(
				"Average Marks In Maths");
		outerRowHeader.createCell((short) 3).setCellValue(
				"Average Marks In Biology");
		HSSFRow outerRowContent = sheet.createRow(rowNum++);
		outerRowContent.createCell((short) 0).setCellValue(
				phyMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 1).setCellValue(
				chemMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 2).setCellValue(
				mathMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 3).setCellValue(
				bioMarks / studentDetailsList.size());
		HSSFRow blankRow3 = sheet.createRow(rowNum++);
		blankRow3.createCell((short) 0).setCellValue("");
		return workBook;
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res) {
		doPost(req, res);
	}
}

PdfCreator.java also a servlet that generates the PDF from sample data.

package com.mattiz.excelPdf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfWriter;

import java.awt.Color;

public class PdfCreator extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		try {
			Document document = new Document();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PdfWriter.getInstance(document, baos);
			document = createTable(document,
					new PopulationHandler().populateData());
			res.setContentType("application/pdf");
			res.setHeader("Content-disposition", "attachment; filename="
					+ "SchoolReport.pdf");
			res.setContentLength(baos.size());
			OutputStream out = res.getOutputStream();
			baos.writeTo(out);
			out.flush();
			out.close();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private Document createTable(Document document, ClassVO classVO) {
		document.open();
		try {
			HeaderFooter header = new HeaderFooter(new Paragraph(
					"School Report", FontFactory.getFont("Arial", 7)), true);
			document.setHeader(header);
			Font arialSmall = FontFactory.getFont("Arial", 7);
			Font arialMedium = FontFactory.getFont("Arial", 9);
			Table table0 = new Table(4, 2);
			table0.setBorderWidth(0);
			table0.setBorderColor(new Color(0, 0, 255));
			table0.setSpacing(0);
			table0.setPadding(2);
			Font normal21 = new Font(Font.HELVETICA, 11, Font.NORMAL);
			Paragraph para = new Paragraph(30, "School Report", normal21);
			document.add(para);
			table0.addCell(getHeaderLabelCell(arialMedium, "CLASS DETAILS"));
			table0.addCell(getLabelCell(arialSmall, "Class Name"));
			table0.addCell(getContentCell(arialSmall, classVO.getClassName()));
			table0.addCell(getLabelCell(arialSmall, "Age Group"));
			table0.addCell(getContentCell(arialSmall, classVO.getAgeGroup()));
			document.add(table0);
			List<StudentVO> studentDetailList = classVO.getStudentDetails();
			long physicsSum = 0;
			long chemistrySum = 0;
			long mathsSum = 0;
			long biologySum = 0;
			for (int j = 0; j < studentDetailList.size(); j++) {
				StudentVO studentVO = studentDetailList.get(j);
				Table table1 = new Table(4, 6);
				table1.setBorderWidth(0);
				table1.setPadding(2);
				table1.setSpacing(0);
				table1.addCell(getHeaderLabelCell(arialMedium,
						"Student Details"));
				table1.addCell(getNameLabelCell(
						arialSmall,
						studentVO.getFirstName() + " "
								+ studentVO.getLastName()));
				table1.endHeaders();
				table1.addCell(getLabelCell(arialSmall, "Date Of Birth"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getDateOfBirth()));
				table1.addCell(getLabelCell(arialSmall, "Physics"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getPhysicsMarks() + ""));
				physicsSum += studentVO.getPhysicsMarks();
				table1.addCell(getLabelCell(arialSmall, "Grade"));
				table1.addCell(getContentCell(arialSmall, studentVO.getGrade()));
				table1.addCell(getLabelCell(arialSmall, "Chemistry"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getChemistryMarks() + ""));
				chemistrySum += studentVO.getChemistryMarks();
				table1.addCell(getLabelCell(arialSmall, ""));
				table1.addCell(getContentCell(arialSmall, ""));
				table1.addCell(getLabelCell(arialSmall, "Maths"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getMathsMarks() + ""));
				mathsSum += studentVO.getMathsMarks();
				table1.addCell(getLabelCell(arialSmall, ""));
				table1.addCell(getContentCell(arialSmall, ""));
				table1.addCell(getLabelCell(arialSmall, "Biology"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getBiologyMarks() + ""));
				biologySum += studentVO.getBiologyMarks();
				document.add(table1);
			}
			Table table2 = new Table(4, 2);
			table2.setBorderWidth(0);
			table2.setBorderColor(new Color(0, 0, 255));
			table2.setSpacing(0);
			table2.setPadding(2);
			table2.addCell(getHeaderLabelCell(arialMedium, "Statistics"));
			table2.addCell(getLabelCell(arialSmall, "Average In Physics"));
			table2.addCell(getContentCell(arialSmall,
					(physicsSum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Maths"));
			table2.addCell(getContentCell(arialSmall,
					(mathsSum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Chemistry"));
			table2.addCell(getContentCell(arialSmall,
					(chemistrySum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Biology"));
			table2.addCell(getContentCell(arialSmall,
					(biologySum / studentDetailList.size()) + ""));
			document.add(table2);
		} catch (BadElementException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		document.close();
		return document;
	}

	private Cell getLabelCell(Font arialSmall, String arg) {
		Cell cell = null;
		try {
			arialSmall.setStyle(Font.BOLD);
			cell = new Cell(new Paragraph(arg, arialSmall));
			cell.setGrayFill(0.85f);
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getContentCell(Font arialSmall, String arg) {
		Cell cell = null;
		try {
			cell = new Cell(new Paragraph(arg, arialSmall));
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getHeaderLabelCell(Font arialMedium, String arg) {
		Cell cell = null;
		try {
			cell = new Cell(new Paragraph(arg, arialMedium));
			arialMedium.setStyle(Font.BOLD);
			cell.setHeader(true);
			cell.setColspan(4);
			cell.setBorderColor(new Color(255, 0, 0));
			cell.setBackgroundColor(Color.LIGHT_GRAY);
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getNameLabelCell(Font arialSmall, String arg) {
		Cell cc = null;
		try {
			cc = new Cell(new Paragraph(arg, arialSmall));
			cc.setHeader(true);
			cc.setColspan(4);
			cc.setBorderColor(new Color(0, 0, 255));
			cc.setBackgroundColor(Color.LIGHT_GRAY);
			cc.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cc;
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res) {
		doPost(req, res);
	}
}

Next follow the value objects used in the application.

ClassVO.java which is a POJO class.

package com.mattiz.excelPdf;

import java.util.List;

public class ClassVO {

	private String className;
	private String ageGroup;
	private List<StudentVO> studentDetails;
	private Integer averageMarksInPhysics;
	private Integer averageMarksInChemistry;
	private Integer averageMarksInMaths;
	private Integer averageMarksInBiology;

	public String getAgeGroup() {
		return ageGroup;
	}

	public void setAgeGroup(String ageGroup) {
		this.ageGroup = ageGroup;
	}

	public Integer getAverageMarksInBiology() {
		return averageMarksInBiology;
	}

	public void setAverageMarksInBiology(Integer averageMarksInBiology) {
		this.averageMarksInBiology = averageMarksInBiology;
	}

	public Integer getAverageMarksInChemistry() {
		return averageMarksInChemistry;
	}

	public void setAverageMarksInChemistry(Integer averageMarksInChemistry) {
		this.averageMarksInChemistry = averageMarksInChemistry;
	}

	public Integer getAverageMarksInMaths() {
		return averageMarksInMaths;
	}

	public void setAverageMarksInMaths(Integer averageMarksInMaths) {
		this.averageMarksInMaths = averageMarksInMaths;
	}

	public Integer getAverageMarksInPhysics() {
		return averageMarksInPhysics;
	}

	public void setAverageMarksInPhysics(Integer averageMarksInPhysics) {
		this.averageMarksInPhysics = averageMarksInPhysics;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public List<StudentVO> getStudentDetails() {
		return studentDetails;
	}

	public void setStudentDetails(List<StudentVO> studentDetails) {
		this.studentDetails = studentDetails;
	}
}

StudentVO.java also a POJO class

package com.mattiz.excelPdf;

public class StudentVO {

	private String firstName;
	private String lastName;
	private String grade;
	private String dateOfBirth;
	private Integer physicsMarks;
	private Integer chemistryMarks;
	private Integer mathsMarks;
	private Integer biologyMarks;

	public Integer getBiologyMarks() {
		return biologyMarks;
	}

	public void setBiologyMarks(Integer biologyMarks) {
		this.biologyMarks = biologyMarks;
	}

	public Integer getChemistryMarks() {
		return chemistryMarks;
	}

	public void setChemistryMarks(Integer chemistryMarks) {
		this.chemistryMarks = chemistryMarks;
	}

	public Integer getMathsMarks() {
		return mathsMarks;
	}

	public void setMathsMarks(Integer mathsMarks) {
		this.mathsMarks = mathsMarks;
	}

	public Integer getPhysicsMarks() {
		return physicsMarks;
	}

	public void setPhysicsMarks(Integer physicsMarks) {
		this.physicsMarks = physicsMarks;
	}

	public String getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(String dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getGrade() {
		return grade;
	}

	public void setGrade(String grade) {
		this.grade = grade;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
}

PopulationHandler.java is the helper class the provides ad hoc data populated randomly.

package com.mattiz.excelPdf;

import java.util.ArrayList;
import java.util.List;

public class PopulationHandler {
	public ClassVO populateData() {
		ClassVO classVO = new ClassVO();
		classVO.setClassName("V");
		classVO.setAgeGroup("12-14");
		List<StudentVO> studentDetails = new ArrayList<StudentVO>();
		for (int i = 0; i < 15; i++) {
			StudentVO studentVO = new StudentVO();
			studentVO.setFirstName(new String(new char[] { (char) (i + 65 + 1),
					(char) (i + 65 + 2), (char) (i + 65 + 3),
					(char) (i + 65 + 4) }));
			studentVO.setLastName(new String(new char[] { (char) (i + 65 + 4),
					(char) (i + 65 + 3), (char) (i + 65 + 2),
					(char) (i + 65 + 1) }));
			studentVO.setDateOfBirth((i + 10) + "/09/1971");
			studentVO.setGrade((char) (65 + i) + "");
			studentVO.setPhysicsMarks(50 + i);
			studentVO.setChemistryMarks(55 + i);
			studentVO.setMathsMarks(60 + i);
			studentVO.setBiologyMarks(75 + i);
			studentDetails.add(studentVO);
		}
		classVO.setStudentDetails(studentDetails);
		return classVO;
	}
}

My web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>InnerJSTL</display-name>
    <servlet>
        <servlet-name>PdfCreator</servlet-name>
        <servlet-class>com.mattiz.excelPdf.PdfCreator</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ExcelCreator</servlet-name>
        <servlet-class>com.mattiz.excelPdf.ExcelCreator</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PdfCreator</servlet-name>
        <url-pattern>/PdfCreator</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ExcelCreator</servlet-name>
        <url-pattern>/ExcelCreator</url-pattern>
    </servlet-mapping>
</web-app>

home.jsp looks like this:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
            <title>PDF Generator</title>
    </head>
    <body>
        <a href="/ExcelPdf/PdfCreator">PDF</a>
        <br />
        <a href="/ExcelPdf/ExcelCreator">Excel</a>
    </body>
</html>

The application can be called using the following url:
http://localhost:8080//ExcelPdf/home.jsp

After the excel successfully downloads it looks something like this: