diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/csv/CsvCell.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/csv/CsvCell.java index cd6e8e7c4..e06db7b0e 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/csv/CsvCell.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/csv/CsvCell.java @@ -190,6 +190,10 @@ protected void setCellValueImpl(Calendar value) { } this.dateValue = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault()); this.cellType = CellType.NUMERIC; + // Mark the numeric cell as a date so CsvSheet.buildCellValue takes the date + // branch; otherwise it falls back to numberValue (null) and writes an empty + // field, silently dropping the Calendar value. Mirrors the Date/LocalDateTime setters. + this.numericCellType = NumericCellTypeEnum.DATE; } @Override diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/format/CsvRowTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/format/CsvRowTest.java index 0130e78ad..dbe9d571a 100644 --- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/format/CsvRowTest.java +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/format/CsvRowTest.java @@ -208,6 +208,46 @@ void csvWrite_withSqlDateAndTime_producesCorrectFile() throws Exception { Assertions.assertTrue(line.contains("12:30:45"), "CSV should contain time 12:30:45, got: " + line); } + /** + * Real-file integration test: writes a physical CSV file containing a + * {@link Calendar} value via the {@link CsvCell} API, then reads the file + * back to verify the output. + *

+ * Without the fix, {@link CsvCell#setCellValueImpl(Calendar)} sets the cell + * to {@code NUMERIC} but does not mark it as a date + * ({@code numericCellType = NumericCellTypeEnum.DATE}), so + * {@link CsvSheet} takes the number branch in {@code buildCellValue}, + * finds {@code numberValue} null, and writes an empty field - the + * Calendar value is silently lost. The sibling {@code Date} and + * {@code LocalDateTime} setters already set the date type. + */ + @Test + void csvWrite_withCalendar_producesCorrectFile() throws Exception { + File csvFile = new File(tempDir, "calendar-test.csv"); + + Calendar cal = Calendar.getInstance(); + cal.set(2024, Calendar.JANUARY, 15, 12, 30, 45); + cal.set(Calendar.MILLISECOND, 0); + + try (java.io.Writer writer = Files.newBufferedWriter(csvFile.toPath(), StandardCharsets.UTF_8)) { + CsvWorkbook workbook = new CsvWorkbook(writer, null, false, false, StandardCharsets.UTF_8, false); + CsvSheet sheet = (CsvSheet) workbook.createSheet(); + CsvRow row = (CsvRow) sheet.createRow(0); + + // Calendar - without fix: written as an empty field (silent data loss) + Cell cell = row.createCell(0, CellType.NUMERIC); + cell.setCellValue(cal); + + sheet.close(); + } + + List lines = Files.readAllLines(csvFile.toPath(), StandardCharsets.UTF_8); + Assertions.assertEquals(1, lines.size()); + String line = lines.get(0); + Assertions.assertTrue( + line.contains("2024-01-15"), "CSV should contain the calendar date 2024-01-15, got: " + line); + } + private static List modelData() { List data = new ArrayList<>(); data.add(new SimpleCsvData("1", "Jackson", "20"));