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