diff --git a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java index 883264a0..63d3f404 100644 --- a/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java +++ b/src/main/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisService.java @@ -24,6 +24,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Objects; @@ -190,8 +192,10 @@ public byte[] exportSensitivityResultsAsCsv(UUID resultUuid, SensitivityAnalysis ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) { zipOutputStream.putNextEntry(new ZipEntry("sensitivity_result.csv")); + // adding BOM to the beginning of file to help excel in some versions to detect this is UTF-8 encoding bytes + writeUTF8Bom(zipOutputStream); CsvWriterSettings settings = new CsvWriterSettings(); - CsvWriter csvWriter = new CsvWriter(zipOutputStream, settings); + CsvWriter csvWriter = new CsvWriter(zipOutputStream, StandardCharsets.UTF_8, settings); csvWriter.writeHeaders(sensitivityAnalysisCsvFileInfos.getCsvHeaders()); if (selector.getTabSelection() == ResultTab.N) { result.getSensitivities() @@ -223,6 +227,12 @@ public byte[] exportSensitivityResultsAsCsv(UUID resultUuid, SensitivityAnalysis } } + private static void writeUTF8Bom(OutputStream outputStream) throws IOException { + outputStream.write(0xef); + outputStream.write(0xbb); + outputStream.write(0xbf); + } + private static Double nullIfNan(double d) { return Double.isNaN(d) ? null : d; } diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java index e87c3805..a37c8017 100644 --- a/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/SensitivityAnalysisControllerTest.java @@ -636,7 +636,9 @@ void runAndSaveTest() throws Exception { byte[] csvFile = unzip(zipFile); String csvFileAsString = new String(csvFile, StandardCharsets.UTF_8); List actualCsvLines = Arrays.asList(csvFileAsString.split("\n")); - List expectedCsvLines = new ArrayList<>(List.of("functionId,variableId,functionReference,value", + + // Including "\uFEFF" indicates the UTF-8 BOM at the start. + List expectedCsvLines = new ArrayList<>(List.of("\uFEFFfunctionId,variableId,functionReference,value", "l1,GEN,2.9,500.1", "l2,GEN,2.8,500.2")); diff --git a/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java b/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java index 382ba1ab..23362cb0 100644 --- a/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java +++ b/src/test/java/org/gridsuite/sensitivityanalysis/server/service/SensitivityAnalysisServiceTest.java @@ -338,7 +338,9 @@ public void testNoNKStillOK() throws Exception { byte[] csv = unzip(zip); String csvStr = new String(csv, StandardCharsets.UTF_8); List actualLines = Arrays.asList(csvStr.split("\n")); - List expectedLines = new ArrayList<>(List.of("functionId,variableId,functionReference,value", + + // Including "\uFEFF" indicates the UTF-8 BOM at the start. + List expectedLines = new ArrayList<>(List.of("\uFEFFfunctionId,variableId,functionReference,value", "l1,GEN,2.9,500.1", "l2,GEN,2.8,500.2", "l3,LOAD,2.1,500.9")); @@ -357,7 +359,9 @@ public void testNoNKStillOK() throws Exception { byte[] csv2 = unzip(zip2); String csvStr2 = new String(csv2, StandardCharsets.UTF_8); List actualLines2 = Arrays.asList(csvStr2.split("\n")); - List expectedLines2 = new ArrayList<>(List.of("functionId,variableId,contingencyId,functionReference,value,functionReferenceAfter,valueAfter")); + + // Including "\uFEFF" indicates the UTF-8 BOM at the start. + List expectedLines2 = new ArrayList<>(List.of("\uFEFFfunctionId,variableId,contingencyId,functionReference,value,functionReferenceAfter,valueAfter")); actualLines2.sort(String::compareTo); expectedLines2.sort(String::compareTo); @@ -446,7 +450,9 @@ private void testNoN(boolean specific) throws Exception { byte[] csv = unzip(zip); String csvStr = new String(csv, StandardCharsets.UTF_8); List actualLines = Arrays.asList(csvStr.split("\n")); - List expectedLines = new ArrayList<>(List.of("functionId,variableId,contingencyId,functionReference,value,functionReferenceAfter,valueAfter", + + // Including "\uFEFF" indicates the UTF-8 BOM at the start. + List expectedLines = new ArrayList<>(List.of("\uFEFFfunctionId,variableId,contingencyId,functionReference,value,functionReferenceAfter,valueAfter", "l1,GEN,a1,0.0,0.0,2.7,500.3", "l1,GEN,a2,0.0,0.0,2.6,500.4", "l1,GEN,a3,0.0,0.0,2.5,500.5",