diff --git a/libraries-io/pom.xml b/libraries-io/pom.xml
index e92f6e11e1..fa89ebeabe 100644
--- a/libraries-io/pom.xml
+++ b/libraries-io/pom.xml
@@ -5,6 +5,18 @@
4.0.0
libraries-io
libraries-io
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+
+
+
+
com.baeldung
@@ -34,6 +46,11 @@
zip4j
${zip4j.version}
+
+ com.opencsv
+ opencsv
+ ${opencsv.version}
+
@@ -42,6 +59,10 @@
0.27.0
2.4
2.9.0
+ 5.7.1
+ 17
+ 17
+ UTF-8
\ No newline at end of file
diff --git a/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/Application.java b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/Application.java
new file mode 100644
index 0000000000..b84da6229b
--- /dev/null
+++ b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/Application.java
@@ -0,0 +1,4 @@
+package com.baeldung.java.io.pojotocsv;
+
+public record Application(String id, String name, Integer age, String created_at) {
+}
diff --git a/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/ApplicationWithAnnotation.java b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/ApplicationWithAnnotation.java
new file mode 100644
index 0000000000..a0cd158843
--- /dev/null
+++ b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/ApplicationWithAnnotation.java
@@ -0,0 +1,8 @@
+package com.baeldung.java.io.pojotocsv;
+
+import com.opencsv.bean.CsvBindByName;
+import com.opencsv.bean.CsvBindByPosition;
+
+public record ApplicationWithAnnotation(@CsvBindByName(column = "id", required = true) @CsvBindByPosition(position = 1) String id, @CsvBindByName(column = "name", required = true) @CsvBindByPosition(position = 0) String name,
+ @CsvBindByName(column = "age", required = true) @CsvBindByPosition(position = 2) Integer age, @CsvBindByName(column = "position", required = true) @CsvBindByPosition(position = 3) String created_at) {
+}
\ No newline at end of file
diff --git a/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/BeanToCsv.java b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/BeanToCsv.java
new file mode 100644
index 0000000000..f66c16beda
--- /dev/null
+++ b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/BeanToCsv.java
@@ -0,0 +1,55 @@
+package com.baeldung.java.io.pojotocsv;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+import com.opencsv.CSVWriter;
+import com.opencsv.bean.StatefulBeanToCsvBuilder;
+import com.opencsv.exceptions.CsvDataTypeMismatchException;
+import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
+
+public class BeanToCsv {
+
+ public void beanToCSVWithDefault(List applications) throws Exception {
+ try (FileWriter writer = new FileWriter("src/main/resources/application.csv")) {
+ var builder = new StatefulBeanToCsvBuilder(writer).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
+ .withSeparator(',')
+ .build();
+ builder.write(applications);
+ }
+ }
+
+ public void beanToCSVWithCustomHeaderStrategy(List applications) throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {
+ try (FileWriter writer = new FileWriter("src/main/resources/application2.csv")) {
+ var mappingStrategy = new CustomHeaderStrategy();
+ mappingStrategy.setType(Application.class);
+
+ var builder = new StatefulBeanToCsvBuilder(writer).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
+ .withMappingStrategy(mappingStrategy)
+ .build();
+ builder.write(applications);
+ }
+ }
+
+ public void beanToCSVWithCustomPositionStrategy(List applications) throws Exception {
+ try (FileWriter writer = new FileWriter("src/main/resources/application3.csv")) {
+ var builder = new StatefulBeanToCsvBuilder(writer).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
+ .build();
+ builder.write(applications);
+ }
+ }
+
+ public void beanToCSVWithCustomHeaderAndPositionStrategy(List applications) throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {
+ try (FileWriter writer = new FileWriter("src/main/resources/application4.csv")) {
+ var mappingStrategy = new CustomColumnPositionStrategy();
+ mappingStrategy.setType(ApplicationWithAnnotation.class);
+
+ var builder = new StatefulBeanToCsvBuilder(writer).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
+ .withMappingStrategy(mappingStrategy)
+ .build();
+ builder.write(applications);
+ }
+ }
+
+}
diff --git a/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomColumnPositionStrategy.java b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomColumnPositionStrategy.java
new file mode 100644
index 0000000000..204bf3f917
--- /dev/null
+++ b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomColumnPositionStrategy.java
@@ -0,0 +1,12 @@
+package com.baeldung.java.io.pojotocsv;
+
+import com.opencsv.bean.ColumnPositionMappingStrategy;
+import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
+
+public class CustomColumnPositionStrategy extends ColumnPositionMappingStrategy {
+ @Override
+ public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
+ super.generateHeader(bean);
+ return super.getColumnMapping();
+ }
+}
diff --git a/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomHeaderStrategy.java b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomHeaderStrategy.java
new file mode 100644
index 0000000000..8e81c8ec28
--- /dev/null
+++ b/libraries-io/src/main/java/com/baeldung/java/io/pojotocsv/CustomHeaderStrategy.java
@@ -0,0 +1,16 @@
+package com.baeldung.java.io.pojotocsv;
+
+import java.util.Arrays;
+
+import com.opencsv.bean.HeaderColumnNameMappingStrategy;
+import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
+
+public class CustomHeaderStrategy extends HeaderColumnNameMappingStrategy {
+ @Override
+ public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
+ String[] header = super.generateHeader(bean);
+ return Arrays.stream(header)
+ .map(String::toLowerCase)
+ .toArray(String[]::new);
+ }
+}
diff --git a/libraries-io/src/main/resources/application.csv b/libraries-io/src/main/resources/application.csv
new file mode 100644
index 0000000000..d4040e18e1
--- /dev/null
+++ b/libraries-io/src/main/resources/application.csv
@@ -0,0 +1,4 @@
+AGE,CREATED_AT,ID,NAME
+34,2023-08-11,123,Sam
+44,2023-02-11,456,Tam
+54,2023-03-11,890,Jam
diff --git a/libraries-io/src/main/resources/application2.csv b/libraries-io/src/main/resources/application2.csv
new file mode 100644
index 0000000000..92bbced703
--- /dev/null
+++ b/libraries-io/src/main/resources/application2.csv
@@ -0,0 +1,4 @@
+age,created_at,id,name
+34,2023-08-11,123,Sam
+44,2023-02-11,456,Tam
+54,2023-03-11,890,Jam
diff --git a/libraries-io/src/main/resources/application3.csv b/libraries-io/src/main/resources/application3.csv
new file mode 100644
index 0000000000..165107b103
--- /dev/null
+++ b/libraries-io/src/main/resources/application3.csv
@@ -0,0 +1,3 @@
+Sam,123,34,2023-08-11
+Tam,456,44,2023-02-11
+Jam,789,54,2023-03-11
diff --git a/libraries-io/src/main/resources/application4.csv b/libraries-io/src/main/resources/application4.csv
new file mode 100644
index 0000000000..b7999ae227
--- /dev/null
+++ b/libraries-io/src/main/resources/application4.csv
@@ -0,0 +1,4 @@
+name,id,age,created_at
+Sam,123,34,2023-08-11
+Tam,456,44,2023-02-11
+Jam,789,54,2023-03-11
diff --git a/libraries-io/src/test/java/com/baeldung/java/io/pojotocsv/BeanToCsvUnitTest.java b/libraries-io/src/test/java/com/baeldung/java/io/pojotocsv/BeanToCsvUnitTest.java
new file mode 100644
index 0000000000..50cd1b1e0e
--- /dev/null
+++ b/libraries-io/src/test/java/com/baeldung/java/io/pojotocsv/BeanToCsvUnitTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.java.io.pojotocsv;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+import java.io.BufferedReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class BeanToCsvUnitTest {
+
+ List applications = new ArrayList<>();
+ List applicationsWithAnnotation = new ArrayList<>();
+
+ @BeforeEach
+ public void beforeEach() {
+ applications = List.of(new Application("123", "Sam", 34, "2023-08-11"), new Application("456", "Tam", 44, "2023-02-11"), new Application("890", "Jam", 54, "2023-03-11"));
+
+ applicationsWithAnnotation = List.of(new ApplicationWithAnnotation("123", "Sam", 34, "2023-08-11"), new ApplicationWithAnnotation("456", "Tam", 44, "2023-02-11"), new ApplicationWithAnnotation("789", "Jam", 54, "2023-03-11"));
+ }
+
+ @Test
+ public void givenApplicationPOJO_whenUsingDefaultStrategy_thenReceiveCSVFormatWithAscendingOrderOfField() throws Exception {
+ BeanToCsv beanToCsv = new BeanToCsv();
+ beanToCsv.beanToCSVWithDefault(applications);
+ try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of("src/main/resources/application.csv"))) {
+ List content = bufferedReader.lines()
+ .toList();
+ assertThat(content.get(0)).isEqualTo("AGE,CREATED_AT,ID,NAME");
+ assertThat(content.get(1)).isEqualTo("34,2023-08-11,123,Sam");
+ assertThat(content.get(2)).isEqualTo("44,2023-02-11,456,Tam");
+ assertThat(content.get(3)).isEqualTo("54,2023-03-11,890,Jam");
+ }
+ }
+
+ @Test
+ public void givenApplicationPOJO_whenUsingCustomHeaderStrategy_thenReceiveCSVFormatWithCustomHeaders() throws Exception {
+ BeanToCsv beanToCsv = new BeanToCsv();
+ beanToCsv.beanToCSVWithCustomHeaderStrategy(applications);
+ try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of("src/main/resources/application2.csv"))) {
+ List content = bufferedReader.lines()
+ .toList();
+ assertThat(content.get(0)).isEqualTo("age,created_at,id,name");
+ assertThat(content.get(1)).isEqualTo("34,2023-08-11,123,Sam");
+ assertThat(content.get(2)).isEqualTo("44,2023-02-11,456,Tam");
+ assertThat(content.get(3)).isEqualTo("54,2023-03-11,890,Jam");
+ }
+ }
+
+ @Test
+ public void givenApplicationPOJOWithAnnotation_whenUsingCustomPositionStrategy_thenReceiveCSVFormatWithCustomPosition() throws Exception {
+ BeanToCsv beanToCsv = new BeanToCsv();
+ beanToCsv.beanToCSVWithCustomPositionStrategy(applicationsWithAnnotation);
+ try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of("src/main/resources/application3.csv"))) {
+ List content = bufferedReader.lines()
+ .toList();
+ assertThat(content.get(0)).isEqualTo("Sam,123,34,2023-08-11");
+ assertThat(content.get(1)).isEqualTo("Tam,456,44,2023-02-11");
+ assertThat(content.get(2)).isEqualTo("Jam,789,54,2023-03-11");
+ }
+ }
+
+ @Test
+ public void givenApplicationPOJOWithAnnotation_whenUsingCustomHeaderPositionStrategy_thenReceiveCSVFormatWithCustomHeaderPosition() throws Exception {
+ BeanToCsv beanToCsv = new BeanToCsv();
+ beanToCsv.beanToCSVWithCustomHeaderAndPositionStrategy(applicationsWithAnnotation);
+ try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of("src/main/resources/application4.csv"))) {
+ List content = bufferedReader.lines()
+ .toList();
+ assertThat(content.get(0)).isEqualTo("name,id,age,created_at");
+ assertThat(content.get(1)).isEqualTo("Sam,123,34,2023-08-11");
+ assertThat(content.get(2)).isEqualTo("Tam,456,44,2023-02-11");
+ assertThat(content.get(3)).isEqualTo("Jam,789,54,2023-03-11");
+ }
+ }
+}