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,

Comments

  1. Great job for publishing such a nice article. Your article isn’t only useful but it is additionally really informative. Thank you because you have been willing to share information with us. Indian Customs Export Data

    ReplyDelete

Post a Comment

Popular posts from this blog

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

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

Java - DES Encryption and Decryption example

Java - Blowfish Encryption and decryption Example

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

ReactJS - Bootstrap - Buttons

Top 5 Java ORM tools - 2024

Spring Boot 3 + Spring Security 6 + Thymeleaf - Registration and Login Example

File Upload, Download, And Delete - Azure Blob Storage + Spring Boot Example

Java - How to Count the Number of Occurrences of Substring in a String