Kotlin + Spring Boot + Apache Commons Export Data to CSV Example

 Hello everyone, today we will learn how to export and download the data as a CSV file in a Kotlin + Spring Boot project. CSV stands for Comma-Separated-Values and it's a common format for doing a bulk data transfer between systems. For creating and parsing CSV files, we will use Apache Commons' 3rd-party library. 


Project Directory:


Technologies used:

  • Kotlin
  • Spring Boot
  • Apache Commons
  • Spring Data JPA
  • H2DB
  • Maven

Maven[pom.xml]

<?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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev</groupId>
<artifactId>kotlin_springboot_apachecommans_exportcsv</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kotlin_springboot_apachecommans_exportcsv</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<kotlin.version>1.3.72</kotlin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>

Creating the Document

package com.knf.dev.entity

import javax.persistence.*

@Entity
@Table(name = "employee")
class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0
var name: String? = null
var email: String? = null
var country: String? = null
var age = 0
var role: String? = null

constructor() : super() {}
constructor(
name: String?, email: String?, country: String?,
age: Int, role: String?
) : super() {
this.name = name
this.email = email
this.country = country
this.age = age
this.role = role
}
}

Creating the Repository

package com.knf.dev.repository

import com.knf.dev.entity.Employee
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface EmployeeRepository : JpaRepository<Employee, Long>

Creating the Service

package com.knf.dev.service

import java.io.ByteArrayInputStream
import com.knf.dev.entity.Employee
import com.knf.dev.helper.CSVHelper
import com.knf.dev.helper.CSVHelper.employeesToCSV
import com.knf.dev.repository.EmployeeRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service


@Service
class EmployeeService {
@Autowired
var employeeRepository: EmployeeRepository? = null
fun fetchAll(): List<Employee> {
return employeeRepository!!.findAll()
}

fun load(): ByteArrayInputStream {
//save Dummy Data
saveDummyEmployees()
val employees = fetchAll()
return CSVHelper.employeesToCSV(employees)
    }

//save Dummy Data
fun saveDummyEmployees() {

val employees: MutableList<Employee> = ArrayList()

// create dummy employees
employees.add(
Employee(
"Dummy-1", "dummy1@example.com",
"India", 35, "Lead Tester"
)
)
employees.add(
Employee(
"Dummy-2", "dummy2@srovoki.me",
"USA", 25, "Tester"
)
)
employees.add(
Employee(
"Dummy-3", "dummy3@gmail.com",
"Japan", 29, "Sr.Tester"
)
)
employees.add(
Employee(
"Dummy-1", "dummy1@example.com",
"India", 35, "Lead Tester"
)
)
employees.add(
Employee(
"Dummy-2", "dummy2@srovoki.me",
"USA", 25, "Tester"
)
)
employees.add(
Employee(
"Dummy-3", "dummy3@gmail.com",
"Japan", 29, "Sr.Tester"
)
)
employees.add(
Employee(
"Dummy-1", "dummy1@example.com",
"India", 35, "Lead Tester"
)
)
employees.add(
Employee(
"Dummy-2", "dummy2@srovoki.me",
"USA", 25, "Tester"
)
)
employees.add(
Employee(
"Dummy-3", "dummy3@gmail.com",
"Japan", 29, "Sr.Tester"
)
)
employees.add(
Employee(
"Dummy-1", "dummy1@example.com",
"India", 35, "Lead Tester"
)
)
employees.add(
Employee(
"Dummy-2", "dummy2@srovoki.me",
"USA", 25, "Tester"
)
)
employees.add(
Employee(
"Dummy-3", "dummy3@gmail.com",
"Japan", 29, "Sr.Tester"
)
)
employees.add(
Employee(
"Dummy-1", "dummy1@example.com",
"India", 35, "Lead Tester"
)
)
employees.add(
Employee(
"Dummy-2", "dummy2@srovoki.me",
"USA", 25, "Tester"
)
)
employees.add(
Employee(
"Dummy-3", "dummy3@gmail.com",
"Japan", 29, "Sr.Tester"
)
)
employeeRepository?.saveAll(employees)
}
}

Creating the Helper 

package com.knf.dev.helper

import java.io.IOException
import java.io.ByteArrayInputStream
import com.knf.dev.entity.Employee
import java.io.PrintWriter
import org.apache.commons.csv.CSVPrinter
import org.apache.commons.csv.CSVFormat
import java.io.ByteArrayOutputStream
import java.util.*


object CSVHelper {
fun employeesToCSV(employees: List<Employee>): ByteArrayInputStream {
val format = CSVFormat.DEFAULT.withHeader("ID", "Name", "Email",
                  "Age", "Country", "Role")
try {
ByteArrayOutputStream().use({ out ->
CSVPrinter(
PrintWriter(out),
format
).use { csvPrinter ->
for (emp in employees) {
val data: List<String?> = Arrays.asList(
emp.id.toString(),
emp.name, emp.email,
java.lang.String.valueOf(emp.age), emp.country,
emp.role
)
csvPrinter.printRecord(data)
}
csvPrinter.flush()
return ByteArrayInputStream(out.toByteArray())
}
})
} catch (e: IOException) {
throw RuntimeException(
"fail to import data to CSV file: "
+ e.message
)
}
}
}

Creating the Controller

package com.knf.dev.controller

import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity
import org.springframework.core.io.InputStreamResource
import javax.servlet.http.HttpServletResponse
import org.springframework.web.bind.annotation.GetMapping
import com.knf.dev.service.EmployeeService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.MediaType
import org.springframework.stereotype.Controller


@Controller
class EmployeeController {
@Autowired
var employeeService: EmployeeService? = null
@GetMapping("/export-employees")
@Throws(Exception::class)
fun exportCSV(response: HttpServletResponse?):
              ResponseEntity<InputStreamResource> {
val filename = "employees.csv"
val file = InputStreamResource(employeeService!!.load())
return ResponseEntity.ok().header(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=$filename"
)
.contentType(MediaType.parseMediaType("application/csv")).body(file)
}
}

Driver

package com.knf.dev

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class KotlinSpringbootApachecommansExportcsvApplication

fun main(args: Array<String>) {
runApplication<KotlinSpringbootApachecommansExportcsvApplication>(*args)
}

Run 

$ mvn spring-boot:run

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

Open the downloaded CSV file


Download source code




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

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