From fdc67c46621b2971cbe7c92df5da9aa202b26ebc Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sat, 12 Sep 2026 11:33:39 +0200 Subject: [PATCH] WW-5731 fix(jasperreports7): stop using the field delimiter as the CSV record delimiter JasperReport7CsvExporterProvider set both the field and the record delimiter to the configured delimiter, so every CSV export came out as a single line with the rows joined by "," (or whatever struts.jasperReport7.csv.defaultDelimiter / getCsvDelimiter returned). Only the field delimiter is configurable, as in the 6.x plugin; records are separated by JasperReports' default newline again. Co-Authored-By: Claude Opus 5 (1M context) --- .../JasperReport7CsvExporterProvider.java | 1 - .../JasperReport7ResultTest.java | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/plugins/jasperreports7/src/main/java/org/apache/struts2/views/jasperreports7/export/JasperReport7CsvExporterProvider.java b/plugins/jasperreports7/src/main/java/org/apache/struts2/views/jasperreports7/export/JasperReport7CsvExporterProvider.java index a93e4040b6..a11b51d005 100644 --- a/plugins/jasperreports7/src/main/java/org/apache/struts2/views/jasperreports7/export/JasperReport7CsvExporterProvider.java +++ b/plugins/jasperreports7/src/main/java/org/apache/struts2/views/jasperreports7/export/JasperReport7CsvExporterProvider.java @@ -77,7 +77,6 @@ public JRCsvExporter createExporter(ActionInvocation invocation, JasperPrint jas SimpleCsvExporterConfiguration config = new SimpleCsvExporterConfiguration(); config.setFieldDelimiter(reportDelimiter); - config.setRecordDelimiter(reportDelimiter); exporter.setConfiguration(config); SimpleExporterInput input = new SimpleExporterInput(jasperPrint); diff --git a/plugins/jasperreports7/src/test/java/org/apache/struts2/views/jasperreports7/JasperReport7ResultTest.java b/plugins/jasperreports7/src/test/java/org/apache/struts2/views/jasperreports7/JasperReport7ResultTest.java index d1f82d5dc0..191f1a26a3 100644 --- a/plugins/jasperreports7/src/test/java/org/apache/struts2/views/jasperreports7/JasperReport7ResultTest.java +++ b/plugins/jasperreports7/src/test/java/org/apache/struts2/views/jasperreports7/JasperReport7ResultTest.java @@ -21,6 +21,7 @@ import jakarta.servlet.ServletException; import net.sf.jasperreports.engine.JasperCompileManager; import org.apache.struts2.ActionContext; +import org.apache.struts2.ActionInvocation; import org.apache.struts2.junit.StrutsTestCase; import org.apache.struts2.mock.MockActionInvocation; import org.apache.struts2.security.NotExcludedAcceptedPatternsChecker; @@ -244,6 +245,27 @@ public void testExportToCsv() throws Exception { assertThat(response.getContentAsString()).contains("Qux Report"); } + public void testCsvRecordsAreSeparatedByNewlines() throws Exception { + // given + result.setDataSource("{#{'firstName':'Foo', 'lastName':'Bar'}, #{'firstName':'Baz', 'lastName':'Qux'}}"); + result.setReportParameters("#{'title':'Qux'}"); + result.setFormat(JasperReport7Constants.FORMAT_CSV); + invocation.setAction(new JasperReport7Aware() { + @Override + public String getCsvDelimiter(ActionInvocation invocation) { + return ";"; + } + }); + + // when + result.execute(this.invocation); + + // then + String csv = response.getContentAsString(); + assertThat(csv).doesNotContain("Qux Report;Hello"); + assertThat(csv.lines()).containsExactly("Qux Report", "Hello Foo Bar!", "Hello Baz Qux!"); + } + public void testExportToRtf() throws Exception { // given result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");