Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.apache.fesod.sheet.converters.byteconverter.ByteBooleanConverter;
import org.apache.fesod.sheet.converters.byteconverter.ByteNumberConverter;
import org.apache.fesod.sheet.converters.byteconverter.ByteStringConverter;
import org.apache.fesod.sheet.converters.charconverter.CharacterStringConverter;
import org.apache.fesod.sheet.converters.date.DateDateConverter;
import org.apache.fesod.sheet.converters.date.DateNumberConverter;
import org.apache.fesod.sheet.converters.date.DateStringConverter;
Expand Down Expand Up @@ -78,6 +79,7 @@
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.year.YearStringConverter;

/**
* Load default handler
Expand Down Expand Up @@ -111,6 +113,8 @@ private static void initAllConverter() {
putAllConverter(new ByteNumberConverter());
putAllConverter(new ByteStringConverter());

putAllConverter(new CharacterStringConverter());

putAllConverter(new DateNumberConverter());
putAllConverter(new DateStringConverter());

Expand Down Expand Up @@ -147,6 +151,8 @@ private static void initAllConverter() {
putAllConverter(new StringNumberConverter());
putAllConverter(new StringStringConverter());
putAllConverter(new StringErrorConverter());

putAllConverter(new YearStringConverter());
allConverter = Collections.unmodifiableMap(allConverter);
}

Expand All @@ -156,6 +162,7 @@ private static void initDefaultWriteConverter() {
putWriteConverter(new BigIntegerNumberConverter());
putWriteConverter(new BooleanBooleanConverter());
putWriteConverter(new ByteNumberConverter());
putWriteConverter(new CharacterStringConverter());
putWriteConverter(new DateDateConverter());
putWriteConverter(new LocalDateTimeDateConverter());
putWriteConverter(new LocalDateDateConverter());
Expand All @@ -166,6 +173,7 @@ private static void initDefaultWriteConverter() {
putWriteConverter(new LongNumberConverter());
putWriteConverter(new ShortNumberConverter());
putWriteConverter(new StringStringConverter());
putWriteConverter(new YearStringConverter());
putWriteConverter(new FileImageConverter());
putWriteConverter(new InputStreamImageConverter());
putWriteConverter(new ByteArrayImageConverter());
Expand All @@ -177,6 +185,7 @@ private static void initDefaultWriteConverter() {
putWriteStringConverter(new BigIntegerStringConverter());
putWriteStringConverter(new BooleanStringConverter());
putWriteStringConverter(new ByteStringConverter());
putWriteStringConverter(new CharacterStringConverter());
putWriteStringConverter(new DateStringConverter());
putWriteStringConverter(new LocalDateStringConverter());
putWriteStringConverter(new LocalDateTimeStringConverter());
Expand All @@ -187,6 +196,7 @@ private static void initDefaultWriteConverter() {
putWriteStringConverter(new LongStringConverter());
putWriteStringConverter(new ShortStringConverter());
putWriteStringConverter(new StringStringConverter());
putWriteStringConverter(new YearStringConverter());
defaultWriteConverter = Collections.unmodifiableMap(defaultWriteConverter);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.charconverter;

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;

/**
* Character and string converter
*/
public class CharacterStringConverter implements Converter<Character> {
@Override
public Class<?> supportJavaTypeKey() {
return Character.class;
}

@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}

@Override
public Character convertToJavaData(
ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
String stringValue = cellData.getStringValue();
if (stringValue == null || stringValue.isEmpty()) {
return null;
}
if (stringValue.length() > 1) {
throw new IllegalArgumentException(
"Can not convert '" + stringValue + "' to a character, the length must be 1");
}
return stringValue.charAt(0);
}

@Override
public WriteCellData<?> convertToExcelData(
Character value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
return new WriteCellData<>(value.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.year;

import java.time.Year;
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;

/**
* Year and string converter
*/
public class YearStringConverter implements Converter<Year> {
@Override
public Class<?> supportJavaTypeKey() {
return Year.class;
}

@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}

@Override
public Year convertToJavaData(
ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
return DateUtils.parseYear(
cellData.getStringValue(), getYearFormat(contentProperty), globalConfiguration.getLocale());
}

@Override
public WriteCellData<?> convertToExcelData(
Year value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
return new WriteCellData<>(
DateUtils.format(value, getYearFormat(contentProperty), globalConfiguration.getLocale()));
}

private static String getYearFormat(ExcelContentProperty contentProperty) {
if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
return null;
}
return contentProperty.getDateTimeFormatProperty().getFormat();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
Expand Down Expand Up @@ -91,6 +92,8 @@ public class DateUtils {

public static String defaultLocalDateFormat = DATE_FORMAT_10;

public static String defaultYearFormat = "yyyy";

public static final String DEFAULT_LOCAL_TIME_FORMAT = TIME_FORMAT_8;

public static final int SECONDS_PER_MINUTE = 60;
Expand Down Expand Up @@ -328,6 +331,39 @@ public static String format(LocalTime time, String timeFormat, Locale local) {
return time.format(getCacheDateTimeFormat(timeFormat, local));
}

/**
* convert string to year
*
* @param yearString
* @param yearFormat
* @param local
* @return
*/
public static Year parseYear(String yearString, String yearFormat, Locale local) {
if (StringUtils.isEmpty(yearFormat)) {
yearFormat = defaultYearFormat;
}
return Year.parse(yearString, getCacheDateTimeFormat(yearFormat, local));
}

/**
* Format year
*
* @param year Year
* @param yearFormat year format
* @param local local
* @return format string
*/
public static String format(Year year, String yearFormat, Locale local) {
if (year == null) {
return null;
}
if (StringUtils.isEmpty(yearFormat)) {
yearFormat = defaultYearFormat;
}
return year.format(getCacheDateTimeFormat(yearFormat, local));
}

/**
* Format date
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* 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;

import java.io.File;
import java.time.Year;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import org.apache.fesod.sheet.annotation.ExcelProperty;
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.helpers.RoundTripHelper;
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;

/**
* Field-level round trips for the Character and Year converters across every supported format.
* Converter lookup differs by direction: on write, xlsx/xls resolve the wildcard key
* ((type, null)) while CSV forces a STRING target and resolves (type, STRING); on read, every
* format resolves by the concrete cell type key, here (type, STRING).
*/
@Tag(Tags.ROUND_TRIP)
public class CharacterAndYearFieldRoundTripTest extends AbstractExcelTest {

@ParameterizedTest
@ExcelFormatSource
void yearFieldRoundTrip(ExcelFormat format) throws Exception {
File file = createTempFile(format);
List<YearFieldData> data = new ArrayList<>();
YearFieldData row = new YearFieldData();
row.setFlag(Year.of(2026));
data.add(row);

List<YearFieldData> result = RoundTripHelper.writeAndRead(file, YearFieldData.class, data);

Assertions.assertEquals(1, result.size());
Assertions.assertEquals(Year.of(2026), result.get(0).getFlag());
}

@ParameterizedTest
@ExcelFormatSource
void characterFieldRoundTrip(ExcelFormat format) throws Exception {
File file = createTempFile(format);
List<CharacterFieldData> data = new ArrayList<>();
CharacterFieldData row = new CharacterFieldData();
row.setFlag('A');
data.add(row);

List<CharacterFieldData> result = RoundTripHelper.writeAndRead(file, CharacterFieldData.class, data);

Assertions.assertEquals(1, result.size());
Assertions.assertEquals(Character.valueOf('A'), result.get(0).getFlag());
}

@Getter
@Setter
public static class YearFieldData {

@ExcelProperty("flag")
private Year flag;
}

@Getter
@Setter
public static class CharacterFieldData {

@ExcelProperty("flag")
private Character flag;
}
}
Loading