Skip to content

Commit efe89d7

Browse files
alaahongdeleipsxjoy
authored
refactor: remove deprecated format field from ExcelProperty and add comprehensive tests for date formatting (#610)
* refactor: remove deprecated format field from ExcelProperty and add comprehensive tests for date formatting * style: add license header to ExcelPropertyFormatTest.java * refactor: clean up import statements in ExcelPropertyFormatTest.java for clarity and consistency * refactor: update sheet names and comments in ExcelPropertyFormatTest.java for clarity --------- Co-authored-by: DeleiGuo <[email protected]> Co-authored-by: Shuxin Pan <[email protected]>
1 parent d8625e0 commit efe89d7

File tree

2 files changed

+201
-11
lines changed

2 files changed

+201
-11
lines changed

fesod/src/main/java/org/apache/fesod/sheet/annotation/ExcelProperty.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.lang.annotation.Retention;
2525
import java.lang.annotation.RetentionPolicy;
2626
import java.lang.annotation.Target;
27-
import org.apache.fesod.sheet.annotation.format.DateTimeFormat;
2827
import org.apache.fesod.sheet.converters.AutoConverter;
2928
import org.apache.fesod.sheet.converters.Converter;
3029

@@ -74,14 +73,4 @@
7473
* @return Converter
7574
*/
7675
Class<? extends Converter<?>> converter() default AutoConverter.class;
77-
78-
/**
79-
*
80-
* default @see org.apache.fesod.sheet.util.TypeUtil if default is not meet you can set format
81-
*
82-
* @return Format string
83-
* @deprecated please use {@link DateTimeFormat}
84-
*/
85-
@Deprecated
86-
String format() default "";
8776
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.fesod.sheet.annotation;
21+
22+
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
import static org.junit.jupiter.api.Assertions.assertNotNull;
24+
import static org.junit.jupiter.api.Assertions.assertTrue;
25+
import java.io.FileInputStream;
26+
import java.io.IOException;
27+
import java.nio.file.Path;
28+
import java.time.LocalDate;
29+
import java.time.LocalDateTime;
30+
import java.util.ArrayList;
31+
import java.util.Collections;
32+
import java.util.Date;
33+
import java.util.LinkedList;
34+
import java.util.List;
35+
import lombok.Data;
36+
import org.apache.fesod.sheet.FastExcel;
37+
import org.apache.fesod.sheet.annotation.format.DateTimeFormat;
38+
import org.apache.fesod.sheet.context.AnalysisContext;
39+
import org.apache.fesod.sheet.read.listener.ReadListener;
40+
import org.apache.fesod.sheet.util.StringUtils;
41+
import org.apache.poi.ss.usermodel.Row;
42+
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
43+
import org.junit.jupiter.api.Test;
44+
import org.junit.jupiter.api.io.TempDir;
45+
46+
public class ExcelPropertyFormatTest {
47+
48+
@Data
49+
static class FormatSample {
50+
@ExcelProperty()
51+
@DateTimeFormat("yyyy-MMM-dd")
52+
private Date date2;
53+
54+
@ExcelProperty()
55+
@DateTimeFormat("yyyy-MMM-dd")
56+
private LocalDate dateLocalDate2;
57+
}
58+
59+
@Test
60+
public void testSingleFormatSampleWriteAndRead(@TempDir Path tempDir) throws IOException {
61+
List<FormatSample> singleElementList = new LinkedList<>();
62+
FormatSample sample = new FormatSample();
63+
sample.setDate2(new Date());
64+
sample.setDateLocalDate2(LocalDate.of(2025, 2, 1));
65+
singleElementList.add(sample);
66+
String fileName =
67+
tempDir.resolve(System.currentTimeMillis() + "_single.xlsx").toString();
68+
FastExcel.write(fileName, FormatSample.class).sheet("UnitTest").doWrite(singleElementList);
69+
try (FileInputStream fis = new FileInputStream(fileName);
70+
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
71+
Row dataRow = workbook.getSheetAt(0).getRow(1);
72+
assertEquals("yyyy-MMM-dd", dataRow.getCell(0).getCellStyle().getDataFormatString());
73+
assertEquals("yyyy-MMM-dd", dataRow.getCell(1).getCellStyle().getDataFormatString());
74+
}
75+
}
76+
77+
/**
78+
* Test cell format string after writing date format pattern with Chinese characters.
79+
*/
80+
@Data
81+
static class ChinesePatternSample {
82+
@ExcelProperty
83+
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
84+
private Date fullDate;
85+
86+
@ExcelProperty
87+
@DateTimeFormat("yyyy年MM月dd日")
88+
private LocalDate localDate;
89+
}
90+
91+
@Test
92+
public void testChinesePatternFormat(@TempDir Path tempDir) throws IOException {
93+
ChinesePatternSample sample = new ChinesePatternSample();
94+
sample.setFullDate(new Date());
95+
sample.setLocalDate(LocalDate.of(2025, 1, 2));
96+
String fileName = tempDir.resolve("chinese_pattern.xlsx").toString();
97+
FastExcel.write(fileName, ChinesePatternSample.class)
98+
.sheet("ChineseFormat")
99+
.doWrite(Collections.singletonList(sample));
100+
try (FileInputStream fis = new FileInputStream(fileName);
101+
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
102+
Row dataRow = workbook.getSheetAt(0).getRow(1);
103+
assertEquals(
104+
"yyyy年MM月dd日HH时mm分ss秒", dataRow.getCell(0).getCellStyle().getDataFormatString());
105+
assertEquals("yyyy年MM月dd日", dataRow.getCell(1).getCellStyle().getDataFormatString());
106+
}
107+
}
108+
109+
/**
110+
* Test different fields with different formats.
111+
*/
112+
@Data
113+
static class MultiPatternSample {
114+
@ExcelProperty
115+
@DateTimeFormat("yyyy/MM/dd")
116+
private Date dateSlash;
117+
118+
@ExcelProperty
119+
@DateTimeFormat("dd-MM-yyyy")
120+
private LocalDate dateDash;
121+
122+
@ExcelProperty
123+
@DateTimeFormat("yyyy-MM-dd HH:mm")
124+
private LocalDateTime dateTimeMinute;
125+
}
126+
127+
@Test
128+
public void testMultiplePatternsPerRow(@TempDir Path tempDir) throws IOException {
129+
MultiPatternSample s = new MultiPatternSample();
130+
s.setDateSlash(new Date());
131+
s.setDateDash(LocalDate.of(2024, 12, 31));
132+
s.setDateTimeMinute(LocalDateTime.of(2025, 3, 4, 15, 20));
133+
String file = tempDir.resolve("multi_pattern.xlsx").toString();
134+
FastExcel.write(file, MultiPatternSample.class).sheet("MultiFormat").doWrite(Collections.singletonList(s));
135+
try (FileInputStream fis = new FileInputStream(file);
136+
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
137+
Row row = workbook.getSheetAt(0).getRow(1);
138+
assertEquals("yyyy/MM/dd", row.getCell(0).getCellStyle().getDataFormatString());
139+
assertEquals("dd-MM-yyyy", row.getCell(1).getCellStyle().getDataFormatString());
140+
assertEquals("yyyy-MM-dd HH:mm", row.getCell(2).getCellStyle().getDataFormatString());
141+
}
142+
}
143+
144+
/**
145+
* Write Date with pattern, read to String field with annotation pattern, verify the read string matches the formatted value.
146+
*/
147+
@Data
148+
static class WriteDateModel {
149+
@ExcelProperty
150+
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
151+
private Date eventTime;
152+
}
153+
154+
@Data
155+
static class ReadStringModel {
156+
@ExcelProperty
157+
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
158+
private String eventTime; // Should be formatted as string when reading
159+
}
160+
161+
static class CapturingListener implements ReadListener<ReadStringModel> {
162+
private final List<ReadStringModel> list = new ArrayList<>();
163+
164+
@Override
165+
public void invoke(ReadStringModel data, AnalysisContext context) {
166+
list.add(data);
167+
}
168+
169+
@Override
170+
public void doAfterAllAnalysed(AnalysisContext context) {}
171+
172+
List<ReadStringModel> getList() {
173+
return list;
174+
}
175+
}
176+
177+
/**
178+
* Test null date field: should write blank cell and not throw exception if value is not set.
179+
*/
180+
@Data
181+
static class NullDateSample {
182+
@ExcelProperty
183+
@DateTimeFormat("yyyy-MM-dd")
184+
private Date mayBeNull;
185+
}
186+
187+
@Test
188+
public void testNullDateFieldWritesBlank(@TempDir Path tempDir) throws IOException {
189+
NullDateSample sample = new NullDateSample();
190+
String file = tempDir.resolve("null_date.xlsx").toString();
191+
FastExcel.write(file, NullDateSample.class).sheet("Null").doWrite(Collections.singletonList(sample));
192+
try (FileInputStream fis = new FileInputStream(file);
193+
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
194+
Row row = workbook.getSheetAt(0).getRow(1);
195+
assertNotNull(row, "expect row existing");
196+
assertTrue(
197+
StringUtils.isBlank(row.getCell(0).getStringCellValue()),
198+
"Empty date field should write as blank cell");
199+
}
200+
}
201+
}

0 commit comments

Comments
 (0)