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;
@SpringBootApplicationpublic 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
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,