Spring MVC – 20 – PDF View & Excel View

Merhaba Arkadaslar,
Spring MVC farkli farkli teknolojileri view olarak desteklemektedir. Bu bolumde PDF ve Excel view uygulamasini yapacagiz. Basit olarak bir HTML table da yer alan kayitlari excel ve pdf e farkli sekillerde aktarmayi inceleyecegiz.

Kullanacagimiz kutuphaneler ;

pom.xml
Oncelikle gerekli dependency tanimini pom.xml dosyamiza ekleyelim.

	<properties>
		....
		<itext.version>2.1.7</itext.version>
		<poi.version>3.15</poi.version>
		<jxl.version>2.6.12</jxl.version>
	</properties>


....

		<!-- itext -->

		<dependency>
			<groupId>com.lowagie</groupId>
			<artifactId>itext</artifactId>
			<version>${itext.version}</version>
		</dependency>

		<!-- apache poi -->

		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
		<dependency>
		    <groupId>org.apache.poi</groupId>
		    <artifactId>poi</artifactId>
		    <version>${poi.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>

		<!-- jexcel api -->

		<!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
		<dependency>
		    <groupId>net.sourceforge.jexcelapi</groupId>
		    <artifactId>jxl</artifactId>
		    <version>${jxl.version}</version>
		</dependency>
....

Person.java
Uygulamamizda kullanacagimiz domain model sinifimiz ;

package _21.pdfAndExcel.model;

public class Person {

	private String id;
	private String name;
	private String surname;
	private String birthYear;
	
	public Person(String id, String name, String surname, String birthYear) {
		super();
		this.id = id;
		this.name = name;
		this.surname = surname;
		this.birthYear = birthYear;
	}
        //...
        //getters and setters
}

PersonController.java
Controller sinifimizi inceleyecek olursak , @RequestMapping ile istekleri yakaliyoruz (handle request). Ayni isi yapabilecegimiz birden fazla sinif bulunmaktadir , bunlari incelemek adina benzer metotlar tanimadim. Burada dikkat edecek olursak her birine farkli isimlerde viewName vermekteyiz. Bu viewName bilgileri biraz asagida tanimlayacagimiz 21.views.xml dosyasinda yer alan view’lere karsilik gelecektir.

package _21.pdfAndExcel.controller;

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

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import _21.pdfAndExcel.model.Person;

@Controller
public class PersonController {

	@RequestMapping("/persons")
	public ModelAndView handlePersonList() {
		ModelAndView mv = new ModelAndView();
		mv.setViewName("personListView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	@RequestMapping("/pdfExport")
	public ModelAndView pdfExport(HttpServletResponse response) {

		response.setContentType("application/pdf");
		response.addHeader("Content-Disposition", "attachment; filename=exportMy.pdf");

		ModelAndView mv = new ModelAndView();
		mv.setViewName("pdfView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	@RequestMapping(value = "/excelExport", method = { RequestMethod.POST })
	public ModelAndView excelExport(HttpServletResponse response) {

		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", "attachment; filename=myExcelExport.xls");

		ModelAndView mv = new ModelAndView();
		mv.setViewName("excelView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	@RequestMapping(value = "/jExcelExport", method = { RequestMethod.POST })
	public ModelAndView jExcelExport(HttpServletResponse response) {

		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", "attachment; filename=myJExcelExport.xls");

		ModelAndView mv = new ModelAndView();
		mv.setViewName("jExcelView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	@RequestMapping(value = "/xlsExport", method = { RequestMethod.POST })
	public ModelAndView xlsViewExport(HttpServletResponse response) {

		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", "attachment; filename=myXlsExport.xls");

		ModelAndView mv = new ModelAndView();
		mv.setViewName("xlsView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	@RequestMapping(value = "/xlsxExport", method = { RequestMethod.POST })
	public ModelAndView xlsxViewExport(HttpServletResponse response) {

		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition", "attachment; filename=myXlsxExport.xls");

		ModelAndView mv = new ModelAndView();
		mv.setViewName("xlsxView");
		mv.addObject("persons", preparePersons());
		return mv;
	}

	public List<Person> preparePersons() {
		Person person1 = new Person("1", "Levent", "Erguder", "1989");
		Person person2 = new Person("2", "James", "Gosling", "1955");
		Person person3 = new Person("3", "Joshua", "Bloch", "1961");

		List<Person> personList = new ArrayList<Person>();
		personList.add(person1);
		personList.add(person2);
		personList.add(person3);

		return personList;
	}

}

PdfView.java
AbstractPdfView sinifini kalitalim , buildPdfDocument  metodunu override edelim.
com.lowagie.text.Table sinifinini kullanarak basit bir tablo olusturalim.

Spring , PDF destegi/support icin itext library kullanir.

Bu ozelligi kullanabilmek icin AbstractPdfView sinifini extends etmemiz ve buildPdfDocument metodunu override etmemiz gereklidir.

package _21.pdfAndExcel.service.pdf;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.view.document.AbstractPdfView;
import com.lowagie.text.Document;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfWriter;

import _21.pdfAndExcel.model.Person;

public class PdfView extends AbstractPdfView {

	@SuppressWarnings("unchecked")
	@Override
	protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		List<Person> personList = (List<Person>) model.get("persons");

		Table table = new Table(4);
		table.addCell("Id");
		table.addCell("Name");
		table.addCell("Surname");
		table.addCell("BirtYear");

		for (Person person : personList) {
			table.addCell(person.getId());
			table.addCell(person.getName());
			table.addCell(person.getSurname());
			table.addCell(person.getBirthYear());
		}

		document.add(table);
	}

}

Excel view icin birden fazla sinif kullanabiliriz , AbstractExcelView sinifini kalitabiliriz.
Bu sinifi kalittigimizda buildExcelDocument metodunu override etmemiz gereklidir. Bu metot parametre olarak HSSFWorkbook almaktadir.

HSSFWorkbook objesini kullanarak HSSFSheet objesi , HSSFSheet objesini kullanarak da HSSFRow objesi olusturabiliriz. Bu siniflar or.apache.poi.hssrf.usermodel paketinde yer almaktadir.

AbstractExcelView sinifi deprecated olmustur , bu nedenle kullanilmasi pek onerilmez.

ExcelView.java

package _21.pdfAndExcel.service.excel;

import java.util.List;
import java.util.Map;
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;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import _21.pdfAndExcel.model.Person;

@SuppressWarnings("deprecation")
public class ExcelView extends AbstractExcelView {

	@SuppressWarnings("unchecked")
	@Override
	protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		List<Person> personList = (List<Person>) model.get("persons");

		HSSFSheet sheet = workbook.createSheet("Persons");
		HSSFRow header = sheet.createRow(0);
		header.createCell(0).setCellValue("Id");
		header.createCell(1).setCellValue("Name");
		header.createCell(2).setCellValue("Surname");
		header.createCell(3).setCellValue("BirthYear");

		int rowNum = 1;
		for (Person person : personList) {
			HSSFRow row = sheet.createRow(rowNum++);
			row.createCell(0).setCellValue(person.getId());
			row.createCell(1).setCellValue(person.getName());
			row.createCell(2).setCellValue(person.getSurname());
			row.createCell(3).setCellValue(person.getBirthYear());

		}

	}
}

JExcelView.java
Bir baska sinif olarak AbstractJExcelView sinifini kalitip , buildExcelDocument metodunu override edebiliriz. Bu metot parametre olarak jxl.write.WritableWorkbook ‘u kullanmaktadir.
Bu nedenle JExcel Apiyi kullanmaktayiz.

Bu sinif da deprecated durumdadir.

package _21.pdfAndExcel.service.excel;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.springframework.web.servlet.view.document.AbstractJExcelView;
import _21.pdfAndExcel.model.Person;

@SuppressWarnings("deprecation")
public class JExcelView extends AbstractJExcelView {

	@SuppressWarnings("unchecked")
	@Override
	protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		List<Person> personList = (List<Person>) model.get("persons");

		WritableSheet sheet = workbook.createSheet("Revenue Report", 0);
		sheet.addCell(new Label(0, 0, "Id"));
		sheet.addCell(new Label(1, 0, "Name"));
		sheet.addCell(new Label(2, 0, "Surname"));
		sheet.addCell(new Label(3, 0, "BirthYear"));

		int rowNum = 1;
		for (Person person : personList) {

			sheet.addCell(new Label(0, rowNum, person.getId()));
			sheet.addCell(new Label(0, rowNum, person.getName()));
			sheet.addCell(new Label(0, rowNum, person.getSurname()));
			sheet.addCell(new Label(0, rowNum, person.getBirthYear()));
			rowNum++;
		}
	}

}

XLSView.java
Bir baska ornek olarak AbstractXlsView sinifini kalitabiliriz. Yine bu sinif da abstract buildExcelDocument metoduna sahiptir.
Parametre olarak org.apache.poi.ss.usermodel.Workbook almaktadir.

org.apache.poi.ss.usermodel.Sheet ve org.apache.poi.ss.usermodel.Row siniflarini kullaniyoruz.

package _21.pdfAndExcel.service.excel;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.servlet.view.document.AbstractXlsView;
import _21.pdfAndExcel.model.Person;

public class XLSView extends AbstractXlsView {

	@SuppressWarnings("unchecked")
	@Override
	protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		List<Person> personList = (List<Person>) model.get("persons");

		Sheet sheet = workbook.createSheet();

		Row header = sheet.createRow(0);
		header.createCell(0).setCellValue("Id");
		header.createCell(1).setCellValue("Name");
		header.createCell(2).setCellValue("Surname");
		header.createCell(3).setCellValue("BirthYear");

		int rowNum = 1;
		for (Person person : personList) {
			Row row = sheet.createRow(rowNum++);
			row.createCell(0).setCellValue(person.getId());
			row.createCell(1).setCellValue(person.getName());
			row.createCell(2).setCellValue(person.getSurname());
			row.createCell(3).setCellValue(person.getBirthYear());

		}
	}

}

XLSXView.java
Son olarak AbstractXlsxView sinifini kalitalim. Bu sinif da AbstractXlsView sinifina benzer sekilde buildExcelDocument metodunda org.apache.poi.ss.usermodel.Workbook almaktadir.

package _21.pdfAndExcel.service.excel;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.servlet.view.document.AbstractXlsxView;

import _21.pdfAndExcel.model.Person;

public class XLSXView extends AbstractXlsxView {

	@SuppressWarnings("unchecked")
	@Override
	protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		List<Person> personList = (List<Person>) model.get("persons");

		Sheet sheet = workbook.createSheet();
		Row header = sheet.createRow(0);
		header.createCell(0).setCellValue("Id");
		header.createCell(1).setCellValue("Name");
		header.createCell(2).setCellValue("Surname");
		header.createCell(3).setCellValue("BirthYear");

		int rowNum = 1;
		for (Person person : personList) {
			Row row = sheet.createRow(rowNum++);
			row.createCell(0).setCellValue(person.getId());
			row.createCell(1).setCellValue(person.getName());
			row.createCell(2).setCellValue(person.getSurname());
			row.createCell(3).setCellValue(person.getBirthYear());

		}
	}

}

21.pdfAndExcel.xml
Onceki bolumlerde XmlViewResolver ‘i inceledik. View tanimlarini 21.views.xml dosyamizda yapacagiz.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        ">
	
	<context:component-scan base-package="_21.pdfAndExcel" />

	<bean class="org.springframework.web.servlet.view.XmlViewResolver">
	   <property name="location">
	       <value>/WEB-INF/21.views.xml</value>
	   </property>
	</bean>

</beans>

View tanimlarini gerceklestirelim;

21.views.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- PDF view -->
	
	 <bean id="pdfView" class="_21.pdfAndExcel.service.pdf.PdfView"/>
	  
	  <!-- Excel views -->
	  
	 <bean id="excelView" class="_21.pdfAndExcel.service.excel.ExcelView"/>
	 
	 <bean id="jExcelView" class="_21.pdfAndExcel.service.excel.JExcelView"/>
	 
	 <bean id="xlsView" class="_21.pdfAndExcel.service.excel.XLSView"/>
	 
	 <bean id="xlsxView" class="_21.pdfAndExcel.service.excel.XLSXView"/>
     
	  <bean id="personListView" class="org.springframework.web.servlet.view.JstlView">
	        <property name="url" value="WEB-INF/jsp/21.pdfAndExcel.view/myPersons.jsp" />
	  </bean>
    
</beans>

web.xml
web.xml dosyamizda /WEB-INF/21.pdfAndExcel.xml dosyamiz icin konfigurasyonu yapalim.

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>

<init-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>					
	<!-- 		
	 /WEB-INF/01.appContext.xml
	 /WEB-INF/02.00.appContext.xml
	 /WEB-INF/03.multiActionController.xml
	 ...
	--> 
	 /WEB-INF/21.pdfAndExcel.xml				 	

	</param-value> 			
 </init-param>	
<load-on-startup>1</load-on-startup>
</servlet>
...

myPersons.jsp
Son olarak jsp sayfamizi ekleyelim. Jsp dosyamizda basit olarak c:forEach tagi ile table olusturuyoruz. Controller da tanimli url adreslerine karsilik olacak , submit edilecek form’lar tanimliyoruz.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html>
<body>

	<h3>Person List</h3>

	<table border="1px" cellpadding="8px">
		<tr>
			<td>Id</td>
			<td>Name</td>
			<td>Surname</td>
			<td>BirthYear</td>
		</tr>

		<c:forEach items="${persons}" var="person">
			<tr>
				<td><c:out value="${person.id}" /></td>
				<td><c:out value="${person.name}" /></td>
				<td><c:out value="${person.surname}" /></td>
				<td><c:out value="${person.birthYear}" /></td>
			</tr>

		</c:forEach>
	</table>


	<table>
		<tr>
			<td>
				<form id="myForm" action="/injavawetrust.springmvc/pdfExport"
					method="POST">
					<input type="submit" value="PDF export">
					</button>
				</form>
			</td>

			<td>
				<form id="myForm" action="/injavawetrust.springmvc/excelExport"
					method="POST">
					<input type="submit" value="excelExport">
					</button>
				</form>
			</td>

			<td>
				<form id="myForm" action="/injavawetrust.springmvc/jExcelExport"
					method="POST">
					<input type="submit" value="jExcelExport">
					</button>
				</form>
			</td>

			<td>
				<form id="myForm" action="/injavawetrust.springmvc/xlsExport"
					method="POST">
					<input type="submit" value="xlsExport">
					</button>
				</form>
			</td>

			<td>
				<form id="myForm" action="/injavawetrust.springmvc/xlsxExport"
					method="POST">
					<input type="submit" value="xlsxExport">
					</button>
				</form>
			</td>
		</tr>
	</table>
</body>
</html>

Ornegimizi calistirdigimizda ;

http://localhost:8080/injavawetrust.springmvc/persons

person list

Butonlara tiklayarak pdf ve excel dosyalarini indirebilirsiniz.

Github kaynak kodlar / source folder
Injavawetrust-springmvc-tutorial

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *