diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/DefaultConverterLoader.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/DefaultConverterLoader.java index f17d9b62c..2709e69ef 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/DefaultConverterLoader.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/DefaultConverterLoader.java @@ -55,6 +55,9 @@ import org.apache.fesod.sheet.converters.floatconverter.FloatNumberConverter; import org.apache.fesod.sheet.converters.floatconverter.FloatStringConverter; import org.apache.fesod.sheet.converters.inputstream.InputStreamImageConverter; +import org.apache.fesod.sheet.converters.instant.InstantDateConverter; +import org.apache.fesod.sheet.converters.instant.InstantNumberConverter; +import org.apache.fesod.sheet.converters.instant.InstantStringConverter; import org.apache.fesod.sheet.converters.integer.IntegerBooleanConverter; import org.apache.fesod.sheet.converters.integer.IntegerNumberConverter; import org.apache.fesod.sheet.converters.integer.IntegerStringConverter; @@ -73,11 +76,20 @@ import org.apache.fesod.sheet.converters.shortconverter.ShortBooleanConverter; import org.apache.fesod.sheet.converters.shortconverter.ShortNumberConverter; import org.apache.fesod.sheet.converters.shortconverter.ShortStringConverter; +import org.apache.fesod.sheet.converters.sqldate.SqlDateDateConverter; +import org.apache.fesod.sheet.converters.sqldate.SqlDateNumberConverter; +import org.apache.fesod.sheet.converters.sqldate.SqlDateStringConverter; +import org.apache.fesod.sheet.converters.sqltime.SqlTimeDateConverter; +import org.apache.fesod.sheet.converters.sqltime.SqlTimeNumberConverter; +import org.apache.fesod.sheet.converters.sqltime.SqlTimeStringConverter; import org.apache.fesod.sheet.converters.string.StringBooleanConverter; import org.apache.fesod.sheet.converters.string.StringErrorConverter; import org.apache.fesod.sheet.converters.string.StringNumberConverter; import org.apache.fesod.sheet.converters.string.StringStringConverter; import org.apache.fesod.sheet.converters.url.UrlImageConverter; +import org.apache.fesod.sheet.converters.yearmonth.YearMonthDateConverter; +import org.apache.fesod.sheet.converters.yearmonth.YearMonthNumberConverter; +import org.apache.fesod.sheet.converters.yearmonth.YearMonthStringConverter; /** * Load default handler @@ -114,6 +126,18 @@ private static void initAllConverter() { putAllConverter(new DateNumberConverter()); putAllConverter(new DateStringConverter()); + putAllConverter(new SqlDateNumberConverter()); + putAllConverter(new SqlDateStringConverter()); + + putAllConverter(new SqlTimeNumberConverter()); + putAllConverter(new SqlTimeStringConverter()); + + putAllConverter(new InstantNumberConverter()); + putAllConverter(new InstantStringConverter()); + + putAllConverter(new YearMonthNumberConverter()); + putAllConverter(new YearMonthStringConverter()); + putAllConverter(new LocalDateNumberConverter()); putAllConverter(new LocalDateStringConverter()); @@ -157,6 +181,10 @@ private static void initDefaultWriteConverter() { putWriteConverter(new BooleanBooleanConverter()); putWriteConverter(new ByteNumberConverter()); putWriteConverter(new DateDateConverter()); + putWriteConverter(new SqlDateDateConverter()); + putWriteConverter(new SqlTimeDateConverter()); + putWriteConverter(new InstantDateConverter()); + putWriteConverter(new YearMonthDateConverter()); putWriteConverter(new LocalDateTimeDateConverter()); putWriteConverter(new LocalDateDateConverter()); putWriteConverter(new LocalTimeDateConverter()); @@ -178,6 +206,10 @@ private static void initDefaultWriteConverter() { putWriteStringConverter(new BooleanStringConverter()); putWriteStringConverter(new ByteStringConverter()); putWriteStringConverter(new DateStringConverter()); + putWriteStringConverter(new SqlDateStringConverter()); + putWriteStringConverter(new SqlTimeStringConverter()); + putWriteStringConverter(new InstantStringConverter()); + putWriteStringConverter(new YearMonthStringConverter()); putWriteStringConverter(new LocalDateStringConverter()); putWriteStringConverter(new LocalDateTimeStringConverter()); putWriteStringConverter(new LocalTimeStringConverter()); diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantDateConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantDateConverter.java new file mode 100644 index 000000000..d28a47450 --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantDateConverter.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.instant; + +import java.time.Instant; +import java.util.Date; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.fesod.sheet.util.WorkBookUtil; + +/** + * Instant and date converter + * + */ +public class InstantDateConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Instant.class; + } + + @Override + public WriteCellData convertToExcelData( + Instant value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) + throws Exception { + WriteCellData cellData = new WriteCellData<>(value == null ? null : Date.from(value)); + String format = null; + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { + format = contentProperty.getDateTimeFormatProperty().getFormat(); + } + WorkBookUtil.fillDataFormat(cellData, format, DateUtils.defaultDateFormat); + return cellData; + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantNumberConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantNumberConverter.java new file mode 100644 index 000000000..1a900dc35 --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantNumberConverter.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.instant; + +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.poi.ss.usermodel.DateUtil; + +/** + * Instant and number converter + * + *

Excel stores a date as a number without a time zone, so the value is read and written with the default time + * zone of the JVM, the same way {@link java.util.Date} is handled. + */ +public class InstantNumberConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Instant.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.NUMBER; + } + + @Override + public Instant convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + LocalDateTime localDateTime = DateUtils.getLocalDateTime( + cellData.getNumberValue().doubleValue(), DateUtils.isDate1904(contentProperty, globalConfiguration)); + return localDateTime.atZone(ZoneId.systemDefault()).toInstant(); + } + + @Override + public WriteCellData convertToExcelData( + Instant value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + LocalDateTime localDateTime = LocalDateTime.ofInstant(value, ZoneId.systemDefault()); + return new WriteCellData<>(BigDecimal.valueOf( + DateUtil.getExcelDate(localDateTime, DateUtils.isDate1904(contentProperty, globalConfiguration)))); + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantStringConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantStringConverter.java new file mode 100644 index 000000000..477b3b35d --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/instant/InstantStringConverter.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.instant; + +import java.text.ParseException; +import java.time.Instant; +import java.util.Date; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; + +/** + * Instant and string converter + * + */ +public class InstantStringConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Instant.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Instant convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) + throws ParseException { + String stringValue = cellData.getStringValue(); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return DateUtils.parseDate(stringValue, null).toInstant(); + } + return DateUtils.parseDate( + stringValue, contentProperty.getDateTimeFormatProperty().getFormat()) + .toInstant(); + } + + @Override + public WriteCellData convertToExcelData( + Instant value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + Date date = Date.from(value); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new WriteCellData<>(DateUtils.format(date, null)); + } + return new WriteCellData<>(DateUtils.format( + date, contentProperty.getDateTimeFormatProperty().getFormat())); + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDateConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDateConverter.java new file mode 100644 index 000000000..555663a3d --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDateConverter.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.sqldate; + +import java.sql.Date; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.fesod.sheet.util.WorkBookUtil; + +/** + * Sql date and date converter + * + */ +public class SqlDateDateConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public WriteCellData convertToExcelData( + Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) + throws Exception { + WriteCellData cellData = new WriteCellData<>(value); + String format = null; + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { + format = contentProperty.getDateTimeFormatProperty().getFormat(); + } + WorkBookUtil.fillDataFormat(cellData, format, DateUtils.defaultLocalDateFormat); + return cellData; + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateNumberConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateNumberConverter.java new file mode 100644 index 000000000..fbea7cef6 --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateNumberConverter.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.sqldate; + +import java.math.BigDecimal; +import java.sql.Date; +import java.time.LocalDate; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.poi.ss.usermodel.DateUtil; + +/** + * Sql date and number converter + * + */ +public class SqlDateNumberConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.NUMBER; + } + + @Override + public Date convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + LocalDate localDate = DateUtils.getLocalDate( + cellData.getNumberValue().doubleValue(), DateUtils.isDate1904(contentProperty, globalConfiguration)); + return Date.valueOf(localDate); + } + + @Override + public WriteCellData convertToExcelData( + Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + return new WriteCellData<>(BigDecimal.valueOf( + DateUtil.getExcelDate(value, DateUtils.isDate1904(contentProperty, globalConfiguration)))); + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateStringConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateStringConverter.java new file mode 100644 index 000000000..7698e2ced --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqldate/SqlDateStringConverter.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.sqldate; + +import java.sql.Date; +import java.text.ParseException; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; + +/** + * Sql date and string converter + * + */ +public class SqlDateStringConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Date convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) + throws ParseException { + String dateString = cellData.getStringValue(); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return Date.valueOf(DateUtils.parseLocalDate(dateString, null, null)); + } + return Date.valueOf(DateUtils.parseLocalDate( + dateString, contentProperty.getDateTimeFormatProperty().getFormat(), null)); + } + + @Override + public WriteCellData convertToExcelData( + Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new WriteCellData<>(value.toString()); + } + return new WriteCellData<>(DateUtils.format( + value.toLocalDate(), contentProperty.getDateTimeFormatProperty().getFormat())); + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDateConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDateConverter.java new file mode 100644 index 000000000..89aca587f --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDateConverter.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.sqltime; + +import java.sql.Time; +import java.time.LocalDateTime; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.fesod.sheet.util.WorkBookUtil; + +/** + * Sql time and date converter + * + */ +public class SqlTimeDateConverter implements Converter

Excel has no month type, so a month is written as a date cell of the first day of that month, formatted with + * {@link #DEFAULT_FORMAT}, which keeps sorting and date arithmetic in the sheet working. + * + */ +public class YearMonthDateConverter implements Converter { + + /** + * Default format of a month cell + */ + public static final String DEFAULT_FORMAT = "yyyy-MM"; + + @Override + public Class supportJavaTypeKey() { + return YearMonth.class; + } + + @Override + public WriteCellData convertToExcelData( + YearMonth value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) + throws Exception { + WriteCellData cellData = + new WriteCellData<>(value == null ? null : value.atDay(1).atStartOfDay()); + String format = null; + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { + format = contentProperty.getDateTimeFormatProperty().getFormat(); + } + WorkBookUtil.fillDataFormat(cellData, format == null || format.isEmpty() ? null : format, DEFAULT_FORMAT); + return cellData; + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthNumberConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthNumberConverter.java new file mode 100644 index 000000000..4391f7994 --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthNumberConverter.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.yearmonth; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.YearMonth; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.poi.ss.usermodel.DateUtil; + +/** + * YearMonth and number converter + * + *

A month is read from and written to the first day of that month, so the value stays a real date in the sheet. + * + */ +public class YearMonthNumberConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return YearMonth.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.NUMBER; + } + + @Override + public YearMonth convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + LocalDate localDate = DateUtils.getLocalDate( + cellData.getNumberValue().doubleValue(), DateUtils.isDate1904(contentProperty, globalConfiguration)); + return YearMonth.from(localDate); + } + + @Override + public WriteCellData convertToExcelData( + YearMonth value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + return new WriteCellData<>(BigDecimal.valueOf(DateUtil.getExcelDate( + value.atDay(1).atStartOfDay(), DateUtils.isDate1904(contentProperty, globalConfiguration)))); + } +} diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthStringConverter.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthStringConverter.java new file mode 100644 index 000000000..a5061c2ca --- /dev/null +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthStringConverter.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.fesod.sheet.converters.yearmonth; + +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import org.apache.fesod.sheet.converters.Converter; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; + +/** + * YearMonth and string converter + * + */ +public class YearMonthStringConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return YearMonth.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public YearMonth convertToJavaData( + ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String stringValue = cellData.getStringValue(); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return YearMonth.parse(stringValue, DateTimeFormatter.ofPattern(YearMonthDateConverter.DEFAULT_FORMAT)); + } + return YearMonth.parse( + stringValue, + DateTimeFormatter.ofPattern( + contentProperty.getDateTimeFormatProperty().getFormat())); + } + + @Override + public WriteCellData convertToExcelData( + YearMonth value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new WriteCellData<>( + value.format(DateTimeFormatter.ofPattern(YearMonthDateConverter.DEFAULT_FORMAT))); + } + return new WriteCellData<>(value.format(DateTimeFormatter.ofPattern( + contentProperty.getDateTimeFormatProperty().getFormat()))); + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/instant/InstantDataTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/instant/InstantDataTest.java new file mode 100644 index 000000000..ccbc76511 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/instant/InstantDataTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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. + */ + +/* + * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. + * + * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. + */ + +package org.apache.fesod.sheet.converters.instant; + +import java.io.File; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.apache.fesod.sheet.FesodSheet; +import org.apache.fesod.sheet.annotation.ExcelProperty; +import org.apache.fesod.sheet.annotation.format.DateTimeFormat; +import org.apache.fesod.sheet.testkit.Tags; +import org.apache.fesod.sheet.testkit.base.AbstractExcelTest; +import org.apache.fesod.sheet.testkit.enums.ExcelFormat; +import org.apache.fesod.sheet.testkit.listeners.CollectingReadListener; +import org.apache.fesod.sheet.testkit.params.ExcelFormatSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; + +/** + * Round trip tests for the java.time.Instant converters. + * + *

Excel has no time zone, so the values are compared through the default time zone of the JVM. + */ +@Tag(Tags.ROUND_TRIP) +public class InstantDataTest extends AbstractExcelTest { + + @ParameterizedTest + @ExcelFormatSource + void readAndWrite(ExcelFormat format) throws Exception { + File file = createTempFile(format); + FesodSheet.write(file, InstantData.class).sheet().doWrite(data()); + + CollectingReadListener listener = new CollectingReadListener<>(); + FesodSheet.read(file, InstantData.class, listener).sheet().doRead(); + + Assertions.assertEquals(1, listener.getRowCount()); + InstantData row = listener.getFirstRow(); + Assertions.assertEquals(instant("2020-01-01T00:00:00Z"), row.getInstant()); + Assertions.assertEquals(instant("2020-01-01T00:00:00Z"), row.getInstantString()); + Assertions.assertEquals(instant("2021-12-31T00:00:00Z"), row.getInstantFormattedString()); + } + + /** + * The written value only keeps the precision of a second, so compare on the second. + */ + private static Instant instant(String value) { + return Instant.parse(value).truncatedTo(java.time.temporal.ChronoUnit.SECONDS); + } + + private List data() { + List list = new ArrayList(); + InstantData data = new InstantData(); + data.setInstant(Instant.parse("2020-01-01T00:00:00Z")); + data.setInstantString(Instant.parse("2020-01-01T00:00:00Z")); + data.setInstantFormattedString(Instant.parse("2021-12-31T00:00:00Z")); + list.add(data); + return list; + } + + @Getter + @Setter + @EqualsAndHashCode + public static class InstantData { + @ExcelProperty("instant") + private Instant instant; + + @ExcelProperty("instantString") + private Instant instantString; + + @ExcelProperty("instantFormattedString") + @DateTimeFormat("yyyy/MM/dd HH:mm:ss") + private Instant instantFormattedString; + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDataTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDataTest.java new file mode 100644 index 000000000..f843b1cd2 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqldate/SqlDateDataTest.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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. + */ + +/* + * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. + * + * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. + */ + +package org.apache.fesod.sheet.converters.sqldate; + +import java.io.File; +import java.sql.Date; +import java.util.ArrayList; +import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.apache.fesod.sheet.FesodSheet; +import org.apache.fesod.sheet.annotation.ExcelProperty; +import org.apache.fesod.sheet.annotation.format.DateTimeFormat; +import org.apache.fesod.sheet.testkit.Tags; +import org.apache.fesod.sheet.testkit.base.AbstractExcelTest; +import org.apache.fesod.sheet.testkit.enums.ExcelFormat; +import org.apache.fesod.sheet.testkit.listeners.CollectingReadListener; +import org.apache.fesod.sheet.testkit.params.ExcelFormatSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; + +/** + * Round trip tests for the java.sql.Date converters. + */ +@Tag(Tags.ROUND_TRIP) +public class SqlDateDataTest extends AbstractExcelTest { + + @ParameterizedTest + @ExcelFormatSource + void readAndWrite(ExcelFormat format) throws Exception { + File file = createTempFile(format); + FesodSheet.write(file, SqlDateData.class).sheet().doWrite(data()); + + CollectingReadListener listener = new CollectingReadListener<>(); + FesodSheet.read(file, SqlDateData.class, listener).sheet().doRead(); + + Assertions.assertEquals(1, listener.getRowCount()); + SqlDateData row = listener.getFirstRow(); + Assertions.assertEquals(Date.valueOf("2020-01-01"), row.getDate()); + Assertions.assertEquals(Date.valueOf("2020-01-01"), row.getDateString()); + Assertions.assertEquals(Date.valueOf("2021-12-31"), row.getDateFormattedString()); + } + + private List data() { + List list = new ArrayList(); + SqlDateData data = new SqlDateData(); + data.setDate(Date.valueOf("2020-01-01")); + data.setDateString(Date.valueOf("2020-01-01")); + data.setDateFormattedString(Date.valueOf("2021-12-31")); + list.add(data); + return list; + } + + @Getter + @Setter + @EqualsAndHashCode + public static class SqlDateData { + @ExcelProperty("date") + private Date date; + + @ExcelProperty("dateString") + private Date dateString; + + @ExcelProperty("dateFormattedString") + @DateTimeFormat("yyyy/MM/dd") + private Date dateFormattedString; + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDataTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDataTest.java new file mode 100644 index 000000000..5c1635dbe --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/sqltime/SqlTimeDataTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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. + */ + +/* + * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. + * + * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. + */ + +package org.apache.fesod.sheet.converters.sqltime; + +import java.io.File; +import java.sql.Time; +import java.util.ArrayList; +import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.apache.fesod.sheet.FesodSheet; +import org.apache.fesod.sheet.annotation.ExcelProperty; +import org.apache.fesod.sheet.annotation.format.DateTimeFormat; +import org.apache.fesod.sheet.testkit.Tags; +import org.apache.fesod.sheet.testkit.base.AbstractExcelTest; +import org.apache.fesod.sheet.testkit.enums.ExcelFormat; +import org.apache.fesod.sheet.testkit.listeners.CollectingReadListener; +import org.apache.fesod.sheet.testkit.params.ExcelFormatSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; + +/** + * Round trip tests for the java.sql.Time converters. + */ +@Tag(Tags.ROUND_TRIP) +public class SqlTimeDataTest extends AbstractExcelTest { + + @ParameterizedTest + @ExcelFormatSource + void readAndWrite(ExcelFormat format) throws Exception { + File file = createTempFile(format); + FesodSheet.write(file, SqlTimeData.class).sheet().doWrite(data()); + + CollectingReadListener listener = new CollectingReadListener<>(); + FesodSheet.read(file, SqlTimeData.class, listener).sheet().doRead(); + + Assertions.assertEquals(1, listener.getRowCount()); + SqlTimeData row = listener.getFirstRow(); + Assertions.assertEquals(Time.valueOf("13:14:15"), row.getTime()); + Assertions.assertEquals(Time.valueOf("01:02:03"), row.getTimeString()); + Assertions.assertEquals(Time.valueOf("23:59:00"), row.getTimeFormattedString()); + } + + private List data() { + List list = new ArrayList(); + SqlTimeData data = new SqlTimeData(); + data.setTime(Time.valueOf("13:14:15")); + data.setTimeString(Time.valueOf("01:02:03")); + // HH:mm has no seconds, so use a value that the format keeps completely + data.setTimeFormattedString(Time.valueOf("23:59:00")); + list.add(data); + return list; + } + + @Getter + @Setter + @EqualsAndHashCode + public static class SqlTimeData { + @ExcelProperty("time") + private Time time; + + @ExcelProperty("timeString") + private Time timeString; + + @ExcelProperty("timeFormattedString") + @DateTimeFormat("HH:mm") + private Time timeFormattedString; + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthDataTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthDataTest.java new file mode 100644 index 000000000..d60e1049d --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/converters/yearmonth/YearMonthDataTest.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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. + */ + +/* + * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. + * + * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. + */ + +package org.apache.fesod.sheet.converters.yearmonth; + +import java.io.File; +import java.time.YearMonth; +import java.util.ArrayList; +import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.apache.fesod.sheet.FesodSheet; +import org.apache.fesod.sheet.annotation.ExcelProperty; +import org.apache.fesod.sheet.annotation.format.DateTimeFormat; +import org.apache.fesod.sheet.testkit.Tags; +import org.apache.fesod.sheet.testkit.base.AbstractExcelTest; +import org.apache.fesod.sheet.testkit.enums.ExcelFormat; +import org.apache.fesod.sheet.testkit.listeners.CollectingReadListener; +import org.apache.fesod.sheet.testkit.params.ExcelFormatSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; + +/** + * Round trip tests for the java.time.YearMonth converters. + */ +@Tag(Tags.ROUND_TRIP) +public class YearMonthDataTest extends AbstractExcelTest { + + @ParameterizedTest + @ExcelFormatSource + void readAndWrite(ExcelFormat format) throws Exception { + File file = createTempFile(format); + FesodSheet.write(file, YearMonthData.class).sheet().doWrite(data()); + + CollectingReadListener listener = new CollectingReadListener<>(); + FesodSheet.read(file, YearMonthData.class, listener).sheet().doRead(); + + Assertions.assertEquals(1, listener.getRowCount()); + YearMonthData row = listener.getFirstRow(); + Assertions.assertEquals(YearMonth.of(2020, 1), row.getMonth()); + Assertions.assertEquals(YearMonth.of(2020, 1), row.getMonthString()); + Assertions.assertEquals(YearMonth.of(2021, 12), row.getMonthFormattedString()); + } + + private List data() { + List list = new ArrayList(); + YearMonthData data = new YearMonthData(); + data.setMonth(YearMonth.of(2020, 1)); + data.setMonthString(YearMonth.of(2020, 1)); + data.setMonthFormattedString(YearMonth.of(2021, 12)); + list.add(data); + return list; + } + + @Getter + @Setter + @EqualsAndHashCode + public static class YearMonthData { + @ExcelProperty("month") + private YearMonth month; + + @ExcelProperty("monthString") + private YearMonth monthString; + + @ExcelProperty("monthFormattedString") + @DateTimeFormat("yyyy/MM") + private YearMonth monthFormattedString; + } +}