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.
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(); ListuserDetails = 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 ListgetUserDetails() { 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.javapackage 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(Mapmodel, 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.
XlsViewpublic class XlsView extends AbstractXlsView { @Override public void buildExcelDocument(Mapmodel, 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.javapackage 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(Mapmodel, 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.
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.