Spring Boot Export data to PDF example

Hello everyone, today we will learn how to export and download the data as a PDF file in a Spring Boot project.
PDF stands for the Portable Document Format, used to exhibit documents in an electronic form independent of the software, hardware, or operating system they are viewed on.



Technologies used:
  • Spring Boot 
  • iText PDF
  • H2DB
  • Spring Data JPA

Project Directory:




Maven(pom.xml)

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details utilized by Maven to build the project. It contains default values for most projects. Some of the configurations that can be designated in the POM is the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists, and such can withal be designated.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.knf.dev</groupId>
<artifactId>SpringExportPDF</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>

<name>SpringExportPDF</name>
<description>Spring Boot Demo Application</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8
</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.0.6</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>



Model Class(Employee.java)
package com.knf.dev.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employees")
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Column(name = "firstname")
private String firstName;

@Column(name = "lastname")
private String lastName;

protected Employee() {
}

public Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public void setId(Long id) {
this.id = id;
}

public Long getId() {
return this.id;
}

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

public String getFirstName() {
return this.firstName;
}

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

public String getLastName() {
return this.lastName;
}
}
The @Entity annotation specifies that the class is an entity and is mapped to a database table. The @Table annotation specifies the name of the database table to be used for mapping. The @Id annotation specifies the primary key of an entity and the @GeneratedValue provides for the specification of generation strategies for the values of primary keys. The @Column annotation is used to specify the mapped column for a persistent property or field. If no Column annotation is specified, the default value will be applied



DAO layer(EmployeeRepository.java)
package com.knf.dev.repository;

import org.springframework.data.repository.CrudRepository;
import com.knf.dev.model.Employee;

public interface EmployeeRepository
extends CrudRepository<Employee, Long> {
}
Spring @Repository annotation is used to indicate that the class provides the mechanism for storage, retrieval, search, update and delete operation on objects.



PDFGenerator.java
package com.knf.dev.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.knf.dev.model.Employee;

public class PDFGenerator {

private static Logger logger = LoggerFactory.
getLogger(PDFGenerator.class);

public static ByteArrayInputStream employeePDFReport
(List<Employee> employees) {
Document document = new Document();
ByteArrayOutputStream out = new ByteArrayOutputStream();

try {

PdfWriter.getInstance(document, out);
document.open();

// Add Text to PDF file ->
Font font = FontFactory.getFont(FontFactory.COURIER, 14,
BaseColor.BLACK);
Paragraph para = new Paragraph("Employee Table", font);
para.setAlignment(Element.ALIGN_CENTER);
document.add(para);
document.add(Chunk.NEWLINE);

PdfPTable table = new PdfPTable(3);
// Add PDF Table Header ->
Stream.of("ID", "First Name", "Last Name").forEach(headerTitle ->
{
PdfPCell header = new PdfPCell();
Font headFont = FontFactory.
getFont(FontFactory.HELVETICA_BOLD);
header.setBackgroundColor(BaseColor.LIGHT_GRAY);
header.setHorizontalAlignment(Element.ALIGN_CENTER);
header.setBorderWidth(2);
header.setPhrase(new Phrase(headerTitle, headFont));
table.addCell(header);
});

for (Employee employee : employees) {
PdfPCell idCell = new PdfPCell(new Phrase(employee.getId().
toString()));
idCell.setPaddingLeft(4);
idCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
idCell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(idCell);

PdfPCell firstNameCell = new PdfPCell(new Phrase
(employee.getFirstName()));
firstNameCell.setPaddingLeft(4);
firstNameCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
firstNameCell.setHorizontalAlignment(Element.ALIGN_LEFT);
table.addCell(firstNameCell);

PdfPCell lastNameCell = new PdfPCell(new Phrase
(String.valueOf(employee.getLastName())));
lastNameCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
lastNameCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
lastNameCell.setPaddingRight(4);
table.addCell(lastNameCell);
}
document.add(table);

document.close();
} catch (DocumentException e) {
logger.error(e.toString());
}

return new ByteArrayInputStream(out.toByteArray());
}
}



EmployeeController.java
package com.knf.dev.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.knf.dev.model.Employee;
import com.knf.dev.repository.EmployeeRepository;
import com.knf.dev.util.PDFGenerator;

@RestController
@RequestMapping("/api/pdf")
public class EmployeeController {

@Autowired
EmployeeRepository employeeRepository;

@GetMapping(value = "/employees", produces =
MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> employeeReport()
throws IOException {
List<Employee> employees = (List<Employee>) employeeRepository.
findAll();

ByteArrayInputStream bis = PDFGenerator.employeePDFReport(employees);

HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline; filename=employees.pdf");

return ResponseEntity.ok().headers(headers).contentType
(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
}
The @RestController annotation was introduced in Spring 4.0 to simplify the engendering of RESTful web services. It's a convenience annotation that combines @Controller and @ResponseBody.
@RequestMapping annotation maps HTTP requests to handler methods of MVC and REST controllers.



Spring Boot Main Class
package com.knf.dev;

import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.knf.dev.model.Employee;
import com.knf.dev.repository.EmployeeRepository;

@SpringBootApplication
public class SpringExportPdfApplication implements CommandLineRunner {

@Autowired
EmployeeRepository repository;

public static void main(String[] args) {
SpringApplication.run(SpringExportPdfApplication.class, args);
}

@Override
public void run(String... args) throws Exception {

if (repository.count() == 0) {
// save a list of Employees
repository.saveAll(Arrays.asList(new Employee("Adam", "John"),
new Employee("Sibin", "M"),
new Employee("Arun", "Mohan"),
new Employee("Scott", "Morrison"),
new Employee("Hikaru", "Nakamura"),
new Employee("Ishivaka", "Yusuke")));
}

}
}
The @SpringBootApplication annotation is a convenience annotation that combines the @EnableAutoConfiguration, @Configuration and the @ComponentScan annotations.



application.properties

spring.datasource.url=jdbc:h2:mem:knfdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.h2.console.enabled=true



Run & Test 

Github repository download link is provided at the end of this tutorial

Local Setup:

Step 1: Download or clone the source code to a local machine.

Step 2mvn clean install

Step 3: Run the Spring Boot application
mvn spring-boot:run


Hit this URL in your local system, http://localhost:8080/api/pdf/employees



More related topics,

Java - Angular - VueJS - ReactJS

NodeJS - Angular - VueJS - ReactJS

Python - Flask  - Angular - VueJS - ReactJS

Popular posts from this blog

Spring boot video streaming example-HTML5

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Spring Boot + Mockito simple application with 100% code coverage

Spring Boot + OpenCSV Export Data to CSV Example

Custom Exception Handling in Quarkus REST API

DataTable-Pagination example with Spring boot, jQuery and ajax

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Node JS mini projects with source code - free download

Spring boot web project free download:User Registration System

Java - Blowfish Encryption and decryption Example