Fix IsoFormattingDateDataFormatter
The format used the ISO_OFFSET_DATE_TIME is the wrong one and leads to errors formatting the date. Instead we should have used the ISO_LOCAL_DATE_TIME instead. This commit fixes that and also includes a bug fix for the XLSX variant as that didn't use the overridden method. The correct method for this has been overridden now also formatting the dates/times for that using the ISO_LOCAL_DATE_TIME format. Tests for different types have been added as well, as to make sure this keeps working for newer versions. Closes: #121
This commit is contained in:
@@ -28,7 +28,7 @@ import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||
|
||||
/**
|
||||
* Specialized subclass for additionally formatting the date into an ISO date/time.
|
||||
* Specialized subclass for formatting the date into an ISO date/time and ignore the format as given in the Excel file.
|
||||
*
|
||||
* @author Marten Deinum
|
||||
*
|
||||
@@ -44,6 +44,15 @@ public class IsoFormattingDateDataFormatter extends DataFormatter {
|
||||
super(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatRawCellContents(double value, int formatIndex, String formatString, boolean use1904Windowing) {
|
||||
if (DateUtil.isADateFormat(formatIndex, formatString) && DateUtil.isValidExcelDate(value)) {
|
||||
return super.formatRawCellContents(value, formatIndex, "yyyy-MM-ddTHH:mm:ss",
|
||||
use1904Windowing);
|
||||
}
|
||||
return super.formatRawCellContents(value, formatIndex, formatString, use1904Windowing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatCellValue(Cell cell, FormulaEvaluator evaluator, ConditionalFormattingEvaluator cfEvaluator) {
|
||||
if (cell == null) {
|
||||
@@ -60,7 +69,7 @@ public class IsoFormattingDateDataFormatter extends DataFormatter {
|
||||
|
||||
if (cellType == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell, cfEvaluator)) {
|
||||
LocalDateTime value = cell.getLocalDateTimeCellValue();
|
||||
return (value != null) ? value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) : "";
|
||||
return (value != null) ? value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : "";
|
||||
}
|
||||
return super.formatCellValue(cell, evaluator, cfEvaluator);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.extensions.excel.poi;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.batch.extensions.excel.mapping.PassThroughRowMapper;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class PoiItemReaderTypesTest {
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToReadMultipleTypes() throws Exception {
|
||||
var reader = new PoiItemReader<String[]>();
|
||||
reader.setResource(new ClassPathResource("types.xls"));
|
||||
reader.setRowMapper(new PassThroughRowMapper());
|
||||
reader.setLinesToSkip(1); // Skip header
|
||||
reader.setUserLocale(Locale.US); // Use a Locale to not be dependent on environment
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
|
||||
reader.open(new ExecutionContext());
|
||||
|
||||
var row1 = reader.read();
|
||||
var row2 = reader.read();
|
||||
assertThat(row1).containsExactly("1", "1.0", "5/12/24", "13:14:55", "5/12/24 13:14", "hello world");
|
||||
assertThat(row2).containsExactly("2", "2.5", "8/8/23", "11:12:13", "8/8/23 11:12", "world hello");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToReadMultipleTypesWithDatesAsIso() throws Exception {
|
||||
var reader = new PoiItemReader<String[]>();
|
||||
reader.setResource(new ClassPathResource("types.xls"));
|
||||
reader.setRowMapper(new PassThroughRowMapper());
|
||||
reader.setLinesToSkip(1); // Skip header
|
||||
reader.setUserLocale(Locale.US); // Use a Locale to not be dependent on environment
|
||||
reader.setDatesAsIso(true);
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
reader.open(new ExecutionContext());
|
||||
|
||||
var row1 = reader.read();
|
||||
var row2 = reader.read();
|
||||
assertThat(row1).containsExactly("1", "1.0", "2024-05-12T00:00:00", "1899-12-31T13:14:55", "2024-05-12T13:14:55", "hello world");
|
||||
assertThat(row2).containsExactly("2", "2.5", "2023-08-08T00:00:00", "1899-12-31T11:12:13", "2023-08-08T11:12:13", "world hello");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.extensions.excel.streaming;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.batch.extensions.excel.mapping.PassThroughRowMapper;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class StreamingXlsxTypesTest {
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToReadMultipleTypes() throws Exception {
|
||||
var reader = new StreamingXlsxItemReader<String[]>();
|
||||
reader.setResource(new ClassPathResource("types.xlsx"));
|
||||
reader.setRowMapper(new PassThroughRowMapper());
|
||||
reader.setLinesToSkip(1); // Skip header
|
||||
reader.setUserLocale(Locale.US); // Use a Locale to not be dependent on environment
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
reader.open(new ExecutionContext());
|
||||
|
||||
var row1 = reader.read();
|
||||
var row2 = reader.read();
|
||||
assertThat(row1).containsExactly("1", "1.0", "5/12/24", "13:14:55", "5/12/24 13:14", "hello world");
|
||||
assertThat(row2).containsExactly("2", "2.5", "8/8/23", "11:12:13", "8/8/23 11:12", "world hello");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToReadMultipleTypesWithDatesAsIso() throws Exception {
|
||||
var reader = new StreamingXlsxItemReader<String[]>();
|
||||
reader.setResource(new ClassPathResource("types.xlsx"));
|
||||
reader.setRowMapper(new PassThroughRowMapper());
|
||||
reader.setLinesToSkip(1); // Skip header
|
||||
reader.setUserLocale(Locale.US); // Use a Locale to not be dependent on environment
|
||||
reader.setDatesAsIso(true);
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
reader.open(new ExecutionContext());
|
||||
|
||||
var row1 = reader.read();
|
||||
var row2 = reader.read();
|
||||
assertThat(row1).containsExactly("1", "1.0", "2024-05-12T00:00:00", "1899-12-31T13:14:55", "2024-05-12T13:14:55", "hello world");
|
||||
assertThat(row2).containsExactly("2", "2.5", "2023-08-08T00:00:00", "1899-12-31T11:12:13", "2023-08-08T11:12:13", "world hello");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
BIN
spring-batch-excel/src/test/resources/types.xls
Normal file
BIN
spring-batch-excel/src/test/resources/types.xls
Normal file
Binary file not shown.
BIN
spring-batch-excel/src/test/resources/types.xlsx
Normal file
BIN
spring-batch-excel/src/test/resources/types.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user