Spring MVC PDF and Excel View Example (using iText)

Spring MVC PDF and Excel View Example (using iText) thumbnail
27K
By Dhiraj 05 April, 2017

This tutorial explains about generating PDF and excel documents in Spring web mvc using iText PDF library. It uses the content negotiation view resolver provided by spring to generate PDF and excel views. Here we will be creating a simple spring mvc web application using annotations and java configs. This application will be capable of negotiating views between pdf and excel based on the HTTP request. If you are looking for json, xml and html content view resolver then visit here - content negotiation example - json and xml

Project Structure

Here all the spring config classes are inside the package com.devglan.config and all the static components inside webapp/ui. The jsp pages are defined inside WEB-INF/jsp.

pdf-excel-project-strct

Maven Dependencies

pom.xml

The dependencies here are usual dependencies for a spring mvc application.

spring-webmvc - provides core HTTP integration including filters. Including this dependency automatically includes spring-web.

itext - It is required for pdf view.

poi - It is required for excel view.

maven-war-plugin - This is required to build war package by maven as we are excluding web.xml based configurations.

<modelVersion>4.0.0</modelVersion>
	<groupId>com.devglan</groupId>
	<artifactId>spring-mvc-content-negotiation</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<spring.version>4.3.7.RELEASE</spring.version>
		<jstl.version>1.2</jstl.version>
		<servlet.version>3.0.1</servlet.version>

	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.14</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.14</version>
		</dependency>
		<dependency>
			<groupId>com.lowagie</groupId>
			<artifactId>itext</artifactId>
			<version>2.1.7</version>
		</dependency>
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>itextpdf</artifactId>
			<version>5.5.9</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>spring-mvc-content-negotiation</finalName>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<warName>spring-mvc</warName>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	
Other Interesting Posts
Spring Mvc Annotation Example
Spring JMS ActiveMq Integration Example
Spring MVC AngularJs Integration Example
Spring Hibernate Integration Example
Writing Junit Tests in Spring 4 MVC
Spring Ehcache Cacheable Example
Spring 5 Features and Enhancements

Defining Spring Controller

Following is the controller class which is mapped for /users. It is a normal controller class that returns ModelAndView and based on the requested url the resolver will be identified and corresponding response will be generated.

UserController.java
package com.devglan.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
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 com.devglan.model.UserDetails;
import com.devglan.service.UserService;

@Controller
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value = "/users", method = RequestMethod.GET)
	public ModelAndView userDetails() {
		ModelAndView modelAndView = new ModelAndView();
		List userDetails = userService.getUserDetails();
		modelAndView.addObject("users", userDetails);
		modelAndView.setViewName("userDetails");
		return modelAndView;
	}

}

Defining Spring MVC Service

Following is the service class that generates user details and returns to the controller.

UserServiceImpl.java
package com.devglan.service.impl;

import java.util.Arrays;
import java.util.List;

import org.springframework.stereotype.Service;

import com.devglan.model.UserDetails;
import com.devglan.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	public List getUserDetails() {
		UserDetails ud1 = new UserDetails();
		ud1.setEmail("john@example.com");
		ud1.setFirstName("John");
		ud1.setLastName("Doe");
		UserDetails ud2 = new UserDetails();
		ud2.setEmail("vicky@gmail.com");
		ud2.setFirstName("vicky");
		ud2.setLastName("Ray");
		UserDetails ud3 = new UserDetails();
		ud3.setEmail("abc@yahoo.co.in");
		ud3.setFirstName("abc");
		ud3.setLastName("greg");
		UserDetails ud4 = new UserDetails();
		ud4.setFirstName("xyz");
		ud4.setEmail("xyz@gmail.com");
		ud4.setLastName("Bard");
		return Arrays.asList(ud1, ud2, ud3, ud4);
	}

}

Let us define the POJO now.

UserDetails.java
package com.devglan.model;

public class UserDetails {
	
	private String firstName;
	private String lastName;
	private String email;
	
	//getters and setters goes here

}

Configuring ServletContex in Spring MVC

This implementaion will be automatically detected by SpringServletContainerInitializer which itself is bootstrapped automatically by any Servlet 3.0 container such as tomcat.

AppInitializer.java
package com.devglan.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class AppInitializer implements WebApplicationInitializer {

	public void onStartup(ServletContext container) throws ServletException {

		AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
		ctx.register(WebConfig.class);
		ctx.setServletContext(container);
		ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
		servlet.setLoadOnStartup(1);
		servlet.addMapping("/");
	}

}

Configuring Pdf and Excel view in Spring MVC

ContentNegotiationConfigurer creates a ContentNegotiationManagernand configures it with one or more ContentNegotiationStrategy instances.

configureViewResolvers() will register different view resolvers. Here we are registering view resolvers for pdf, xls and xlsx view. Hence, when a request is made with url ending .xls, a xls view will be rendered and similarly xlsx for view for url ending with .xlsx

WebConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.devglan")
public class WebConfig extends WebMvcConfigurerAdapter {
	
	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		configurer
				.defaultContentType(MediaType.TEXT_HTML)
				.ignoreAcceptHeader(true);
	}
	
	 @Override
	 public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/jsp/", ".jsp").viewClass(JstlView.class);
		registry.enableContentNegotiation(
				new XlsView(),
				new XlsxView(),
				new PdfView());
	}
	
	@Override
	public void addResourceHandlers(final ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/js/**").addResourceLocations("/ui/js/");
		registry.addResourceHandler("/css/**").addResourceLocations("/ui/css/");
	}

}

Now, let us define thee different view classes configured above. Following class will create the pdf view using the model objects which we sent through our controller class.

PdfView.java
package com.devglan.view;

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.devglan.model.UserDetails;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class PdfView extends AbstractPdfView {

	@Override
	public void buildPdfDocument(Map model, Document document, PdfWriter writer,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		@SuppressWarnings("unchecked")
		List users = (List) model.get("users");

		PdfPTable table = new PdfPTable(3);
		table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);

		table.addCell("First Name");
		table.addCell("Last Name");
		table.addCell("Email");

		for (UserDetails user : users) {
			table.addCell(user.getFirstName());
			table.addCell(user.getLastName());
			table.addCell(user.getEmail());
		}
		document.add(table);

	}

}

Following is the Xls view. It will create the Xls view using the model objects which we sent through our controller class.

XlsView
public class XlsView extends AbstractXlsView {

	@Override
	public void buildExcelDocument(Map model, Workbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		response.setHeader("Content-Disposition", "attachment; filename=\"users.xls\"");

		@SuppressWarnings("unchecked")
		List users = (List) model.get("users");

		Sheet sheet = workbook.createSheet("Users Xls");

		Row header = sheet.createRow(0);
		header.createCell(0).setCellValue("First Name");
		header.createCell(1).setCellValue("Last Name");
		header.createCell(2).setCellValue("Email");

		int rowCount = 1;
		for (UserDetails user : users) {
			Row fruitRow = sheet.createRow(rowCount++);
			fruitRow.createCell(0).setCellValue(user.getFirstName());
			fruitRow.createCell(1).setCellValue(user.getLastName());
			fruitRow.createCell(2).setCellValue(user.getEmail());
		}
	}
}

Following is the Xlsx View class. It will create the Xlsx view using the model objects which we sent through our controller class.

XlsxView.java
package com.devglan.view;

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 com.devglan.model.UserDetails;

public class XlsxView extends AbstractXlsxView {

	@Override
	public void buildExcelDocument(Map model, Workbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		response.setHeader("Content-Disposition", "attachment; filename=\"users.xlsx\"");

		@SuppressWarnings("unchecked")
		List users = (List) model.get("users");

		Sheet sheet = workbook.createSheet("Users Xlsx");

		Row header = sheet.createRow(0);
		header.createCell(0).setCellValue("First Name");
		header.createCell(1).setCellValue("Last Name");
		header.createCell(2).setCellValue("Email");

		int rowCount = 1;
		for (UserDetails user : users) {
			Row fruitRow = sheet.createRow(rowCount++);
			fruitRow.createCell(0).setCellValue(user.getFirstName());
			fruitRow.createCell(1).setCellValue(user.getLastName());
			fruitRow.createCell(2).setCellValue(user.getEmail());
		}

	}
}

Client Side Implementation

Following is the jsp page that will be rendered when no requests with any file extension.

userDetails.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title> Spring Boot Example</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
    <script src="js/jquery-2.2.1.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
</head>
<body>
<div>
<div class="container" style="margin:50px">
    <div class="row text-center"><strong> User Details</strong></div>
    <div class="row" style="border:1px solid green;padding:10px">
        <div class="col-md-3 text-center"><strong>First Name</strong></div>
        <div class="col-md-3 text-center"><strong>Last Name</strong></div>
        <div class="col-md-3 text-center"><strong>Email</strong></div>
    </div>
        <c:forEach var="user" items="${users}">
            <div class="row" style="border:1px solid green;padding:10px">
            <div class="col-md-3 text-center">${user.firstName}</div>
            <div class="col-md-3 text-center" >${user.lastName}</div>
                <div class="col-md-3 text-center">${user.email}</div>
            </div>
        </c:forEach>

</div>
</div>
</body>
</html>

Run Spring MVC Application

1. Deploy the application to tomcat.

2. Hit the url as http://localhost:8080/spring-mvc-content-negotiation-example/users.pdf and you can see following result.

contentnegotiatingviewresolver-pdf-view

2. Similarly you can hit http://localhost:8080/spring-mvc-content-negotiation-example/users.xls for xls view and http://localhost:8080/spring-mvc-content-negotiation-example/users.xlsx for xlsx view.

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download source

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring MVC