Export & Import CSV File dengan Spring Boot

Export & Import CSV File dengan Spring Boot

Introduction

Hallo guys, oke dalam artikel kali ini kita akan mencoba mengeksport data dari file csv ke database postgresql dan sebaliknya mengimport data dari postgresql ke dalam bentuk CSV.

Apa itu CSV File ?

CSV adalah singkatan dari Comma Separated Values, sesuai dengan namanya value dari file ini dipisah menggunakan comma. dan itu adalah CSV file, simple kan wkwkkwwk πŸ˜„πŸ˜„πŸ˜„

Jika kalian membuka file csv pake notepad, maka kurang lebih bentukannya akan seperti ini.

gambar diatas terdiri dari dua element yaitu header dan value

  • header : yang berisi nim, nama dan email

  • value : yang berisi nilai-nilai dari header nya

simple kan, nah file itu nantinya akan kita gunakan dalam project ini, namun kalian tidak perlu membuat dari awal, kalian cukup clone repo ini (ada dibagian kesimpulan) dan gunakan sesuai dengan instruksi yang ada. Yuk ahh Markoding (Mari kita coding πŸ˜„πŸ˜„πŸ˜„)

Development

Oke seperti biasa kita bikin dulu project nya, kalian bisa bikin di Intejjlidea langsung ato di Sprint Initializr.

Prerequisites

Oiya, disini saya menggunakan Java Versi 17 dan akan menggunakan Gradle Build Tools (Pake gradle dong biar kekinian wkwkw), tapi itu opsional sih yaa jadi untuk yang part itu tolong disesuaikan dengan versi java local kalian dan pake gradle ato maven sama aja.

  • Sudah Terinstall JDK

  • Pake Gradle / Maven

Buat Project Spring Boot

Yuk ah, sesuaikan template project seperti ini

Jika sudah, kalian bisa generate project dan buka di Inteljidea, kemudian tambahan library untuk memproses csv file nya.

implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.9.0'

Setup Properties File

Langkah selanjutnya yaitu setup properties file, disini saya rename file application.properties menjadi application.yml karena biar memudahkan kita menulis properties nya.

Sebelum itu kita siapkan dulu satu buat database pada postgresql, misalkan namanya import-csv.

Berikut adalah isi dari properties nya

server:
  port: 8081

spring:
  application:
    name: spring-boot-import-csv
  datasource:
    url: jdbc:postgresql://localhost:5432/import-csv
    username: postgres
    password: postgres
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQL81Dialect
        format_sql: true
    hibernate:
      ddl-auto: update
  servlet:
    multipart:
      max-file-size: 2MB
      max-request-size: 2MB

Untuk part database username dan password tolong sesuaikan lagi dengan credentials yang digunakan ditempat kalian

Membuat Class Model dan Repository

Sesudah kita membuat properties file, langkah selanjutnya yaitu membuat model dan repository. Untuk itu buat sebuah class dengan nama Mahasiswa pada package models.

package id.ten.springimportcsvpostgres.models;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

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

@Data
@Table(name = "mahasiswas")
@Entity
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Mahasiswa {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long idl;

    @Column(name = "nim")
    private String nim;

    @Column(name = "nama")
    private String nama;

    @Column(name = "email")
    private String email;
}

Class Mahasiswa ini adalah representasi dari data csv yang akan kita olah nanti, bisa dilihat dibagian atribut, Mahasiswa mempunyai id, nim, nama dan email.

Next, buat sebuah folder dengan nama repositories dan buat sebuah interface untuk kepentingan data access object nya dengan nama MahasiswaRepository.java

package id.ten.springimportcsvpostgres.repository;

import id.ten.springimportcsvpostgres.models.Mahasiswa;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MahasiswaRepository extends JpaRepository<Mahasiswa, Long> {
}

Membuat Class CSVHelper

Class CSVHelper ini bertugas untuk mengolah data CSV supaya bisa disimpan ke dalam database, mengolah data dalam database supaya bisa diexport ke CSV kembali dan mengecek apakah file yang diupload itu bertipe csv atau bukan

Untuk itu buat sebuah folder dengan nama helpers dan buat sebuah class dengan nama CSVHelper.java

public class CSVHelper {

    public static String TYPE = "text/csv";
    static String[] HEADERs = { "nim", "nama", "email" };

    public static boolean hasCSVFormat(MultipartFile file) {
        final String contentType = file.getContentType();
        if(TYPE.equals(contentType) || file.getContentType().equals("application/vnd.ms-excel")) {
            return true;
        }
        return false;
    }

    public static List<Mahasiswa> transformCSVToList(InputStream inputStream) {
        try(BufferedReader fileReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            CSVParser csvParser = new CSVParser(fileReader,
                    CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());) {

            List<Mahasiswa> mahasiswaList = new ArrayList<>();

            Iterable<CSVRecord> csvRecords = csvParser.getRecords();

            for(CSVRecord csvRecord: csvRecords) {
                Mahasiswa mahasiswa = Mahasiswa.builder()
                        .nim(csvRecord.get("nim"))
                        .nama(csvRecord.get("nama"))
                        .email(csvRecord.get("email"))
                        .build();

                mahasiswaList.add(mahasiswa);
            }

            return mahasiswaList;
        }catch (IOException e) {
            throw new RuntimeException("Failed to parse CSV file "+ e.getMessage());
        }
    }

    public static ByteArrayInputStream mahasiswaToCSV(List<Mahasiswa> mahasiswaList) {
        final CSVFormat format = CSVFormat.DEFAULT.withQuoteMode(QuoteMode.MINIMAL);

        try(ByteArrayOutputStream out = new ByteArrayOutputStream();
            CSVPrinter csvPrinter = new CSVPrinter(new PrintWriter(out), format);)  {

            for(Mahasiswa mahasiswa: mahasiswaList) {
                List<String> data = Arrays.asList(
                        mahasiswa.getNim(),
                        mahasiswa.getNama(),
                        mahasiswa.getEmail()
                );
                csvPrinter.printRecord(data);
            }
            csvPrinter.flush();
            return new ByteArrayInputStream(out.toByteArray());
        }catch (IOException e) {
            throw new RuntimeException("fail to import data to CSV file: " + e.getMessage());
        }
    }
}

Membuat Class CSVService

Untuk keperluan bisnis proses, buatlah sebuah class CSVService.java pada folder services. Class ini akan memanggil helper sesuai dengan behaviour dari class ini.

@Service
@AllArgsConstructor
public class CSVService {

    private MahasiswaRepository mahasiswaRepository;

    public void save(MultipartFile file) {
        try {
            final List<Mahasiswa> mahasiswaList = CSVHelper.transformCSVToList(file.getInputStream());
            mahasiswaRepository.saveAll(mahasiswaList);
        }catch (IOException e) {
            throw new RuntimeException("fail to store csv data: " + e.getMessage());
        }
    }

    public ByteArrayInputStream load() {
        List<Mahasiswa> mahasiswaList = mahasiswaRepository.findAll();

        ByteArrayInputStream inputStream = CSVHelper.mahasiswaToCSV(mahasiswaList);

        return inputStream;
    }
}

Membuat Class CSVController

Untuk endpoint nya, kita buat sebuah folder dengan nama controller dan buat sebuah class dengan nama CSVController.java. Endpoint yang saya buat dicontroller ini yaitu /api/v1/csv/download dan /api/v1/csv/upload

@RestController
@RequestMapping("/api/v1/csv")
@AllArgsConstructor
public class CSVController {

    private CSVService csvService;

    @PostMapping("/upload")
    public ResponseEntity<String> uploadCSV(@RequestParam("file")MultipartFile file) {
        try {
            csvService.save(file);
            return ResponseEntity.status(HttpStatus.OK).body("Upload CSV Sukses");
        }catch (Exception e) {
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body("Terjadi kesalahan pada saat upload");
        }
    }

    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile() {
        String filename = "mahasiswa-data.csv";

        InputStreamResource file  = new InputStreamResource(csvService.load());

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename)
                .contentType(MediaType.parseMediaType("application/csv"))
                .body(file);
    }
}

Testing Postman

Jalankan aplikasi sampai port yang aktif muncul dalam log

Testing Export CSV

Buka Postman dan masukan url localhost:8081/api/v1/csv/upload dengan method POST, Untuk mengupload file csv nya dibagian Body pilih form-data dan masukan satu variable dengan nama file dan letakan file csv disana. Jika export berhasil maka response nya seperti ini.

Kemudian untuk mengeceknya silahkan buka didalam database dan cek di tabel Mahasiswa, jika data nya sesuai dengan csv maka proses upload berhasil.

Testing Export CSV.

Untuk mengetest endpoint ini, silahkan paste url ini dibrowser, localhost:8081/api/v1/csv/upload dan jika response dari browser nya yaitu proses download file csv berarti endpoint nya sudah berhasil

Conclusion

Dalam artikel ini kalian sudah mengetahui cara untuk mengimport data csv ke dalam database dan mengekport balik data dalam database ke bentuk csv. Jika kalian masih bingung silahkan hubungi saya. Terima kasih ...

Link project bisa kalian unduh di https://github.com/teten-nugraha/spring-import-csv-postgres

Did you find this article valuable?

Support Teten Nugraha by becoming a sponsor. Any amount is appreciated!

Β