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. 
<?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>springboot-export-pdf</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>

<name>springboot-export-pdf</name>
<description>Spring Boot Demo Application</description>

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

<properties>
<java.version>17</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.5.13.3</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>


Create Employee Entity

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 an entity's primary key, 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


Create User Repository

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 indicates 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());
}
}


Create employee controller

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 Driver

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.


Download the complete source code - click here                                        

Local Setup and Run the application

Step1: Download or clone the source code from GitHub to the local machine - Click here

Step 2: mvn clean install

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

Hit this URL in your local system, http://localhost:8080/export




More related topics,

Popular posts from this blog

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

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete