diff --git a/pom.xml b/pom.xml index c4c2904..059f5f9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.vaadin.addons.flowingcode grid-exporter-addon - 2.2.2-SNAPSHOT + 2.3.0-SNAPSHOT Grid Exporter Add-on Grid Exporter Add-on for Vaadin Flow diff --git a/src/main/java/com/flowingcode/vaadin/addons/gridexporter/CsvInputStreamFactory.java b/src/main/java/com/flowingcode/vaadin/addons/gridexporter/CsvInputStreamFactory.java index 6b27ba3..efb8386 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/gridexporter/CsvInputStreamFactory.java +++ b/src/main/java/com/flowingcode/vaadin/addons/gridexporter/CsvInputStreamFactory.java @@ -28,6 +28,7 @@ import java.io.OutputStreamWriter; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; @@ -72,7 +73,14 @@ public InputStream createInputStream() { PipedOutputStream out = new PipedOutputStream(in); new Thread( () -> { - try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { + try ( + OutputStreamWriter os = new OutputStreamWriter(out, exporter.getCsvCharset()); + CSVWriter writer = new CSVWriter(os)) { + if (StandardCharsets.UTF_8.equals(exporter.getCsvCharset())) { + // write BOM + os.write(0xfeff); + } + writer.writeNext(headers); writer.writeAll(data); if (footers.length > 0) { diff --git a/src/main/java/com/flowingcode/vaadin/addons/gridexporter/GridExporter.java b/src/main/java/com/flowingcode/vaadin/addons/gridexporter/GridExporter.java index 629d396..82f5d15 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/gridexporter/GridExporter.java +++ b/src/main/java/com/flowingcode/vaadin/addons/gridexporter/GridExporter.java @@ -39,6 +39,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.charset.Charset; import java.text.DateFormat; import java.text.DecimalFormat; import java.util.Comparator; @@ -102,6 +103,8 @@ public class GridExporter implements Serializable { private List footerToolbarItems; + private SerializableSupplier csvCharset; + private GridExporter(Grid grid) { this.grid = grid; } @@ -554,4 +557,17 @@ public void setFooterToolbarItems(List footerToolbarItems) { this.footerToolbarItems = footerToolbarItems; } + /** + * Charset to use when exporting the CSV file. + * + * @return CSV file charset or default one. + */ + public Charset getCsvCharset() { + return csvCharset == null ? Charset.defaultCharset() : csvCharset.get(); + } + + public void setCsvCharset(SerializableSupplier charset) { + this.csvCharset = charset; + } + } diff --git a/src/test/java/com/flowingcode/vaadin/addons/gridexporter/GridExporterDemo.java b/src/test/java/com/flowingcode/vaadin/addons/gridexporter/GridExporterDemo.java index a8440d1..6c16bc7 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/gridexporter/GridExporterDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/gridexporter/GridExporterDemo.java @@ -35,6 +35,7 @@ import com.vaadin.flow.router.Route; import java.io.IOException; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.List; @@ -81,6 +82,7 @@ public GridExporterDemo() throws EncryptedDocumentException, IOException { exporter.setTitle("People information"); exporter.setFileName( "GridExport" + new SimpleDateFormat("yyyyddMM").format(Calendar.getInstance().getTime())); + exporter.setCsvCharset(() -> StandardCharsets.UTF_8); TextField filterField = new TextField(); filterField.setPlaceholder("Filter by"); diff --git a/src/test/java/com/flowingcode/vaadin/addons/gridexporter/test/SerializationTest.java b/src/test/java/com/flowingcode/vaadin/addons/gridexporter/test/SerializationTest.java index 0f920e2..8f16c4c 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/gridexporter/test/SerializationTest.java +++ b/src/test/java/com/flowingcode/vaadin/addons/gridexporter/test/SerializationTest.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.nio.charset.StandardCharsets; import org.junit.Assert; import org.junit.Test; @@ -46,7 +47,9 @@ private void testSerializationOf(Object obj) throws IOException, ClassNotFoundEx public void testSerialization() throws ClassNotFoundException, IOException { try { Grid grid = new Grid<>(); - testSerializationOf(GridExporter.createFor(grid)); + GridExporter exporter = GridExporter.createFor(grid); + exporter.setCsvCharset(() -> StandardCharsets.ISO_8859_1); + testSerializationOf(exporter); } catch (Exception e) { Assert.fail("Problem while testing serialization: " + e.getMessage()); }