Skip to content

Commit

Permalink
Merge pull request #191 from croz-ltd/feature_addEnumSupportToExcel
Browse files Browse the repository at this point in the history
Add support for resolving enum description from message source in excel
  • Loading branch information
jzrilic authored Jan 24, 2024
2 parents fc8808f + 1f36ccf commit cb1ee62
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
Expand All @@ -41,8 +42,8 @@ public class NrichExcelAutoConfiguration {

@ConditionalOnProperty(name = "nrich.excel.default-converter-enabled", havingValue = "true", matchIfMissing = true)
@Bean
public CellValueConverter defaultCellValueConverter() {
return new DefaultCellValueConverter();
public CellValueConverter defaultCellValueConverter(MessageSource messageSource) {
return new DefaultCellValueConverter(messageSource);
}

@ConditionalOnMissingBean
Expand Down
8 changes: 5 additions & 3 deletions nrich-excel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ To be able to use this module following configuration is required:
public class ApplicationConfiguration {

@Bean
public CellValueConverter defaultCellValueConverter() {
return new DefaultCellValueConverter();
public CellValueConverter defaultCellValueConverter(MessageSource messageSource) {
return new DefaultCellValueConverter(messageSource);
}

@Bean
Expand All @@ -37,7 +37,9 @@ public class ApplicationConfiguration {
```

`CellValueConverter` is responsible for converting objects to values to be written in excel. Users can provided their own implementations and/or use
`DefaultCellValueConverter`.
`DefaultCellValueConverter`. `DefaultCellValueConverter` supports writing of dates, numbers and enums to excel (for other types toString() method is called before writing to excel).
Enum value to be written to excel can be provided through messages.properties file in the form `fullyQualifiedClassName.enumValue.description` and if present will be written to
excel instead of value.

`TypeDataFormatUtil` is responsible for resolving a list of `TypeDataFormat` instances that decide with what format a specific class will be written to excel. It accepts a list of formats for value
conversion (`dateFormat`, `dateTimeFormat`, `integerNumberFormat`, `decimalNumberFormat`), option should dates be written with time component or not
Expand Down
1 change: 1 addition & 0 deletions nrich-excel/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies {
compileOnly "org.projectlombok:lombok"

implementation "org.springframework:spring-core"
implementation "org.springframework:spring-context"
implementation "org.apache.poi:poi"
implementation "org.apache.poi:poi-ooxml"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import lombok.RequiredArgsConstructor;
import net.croz.nrich.excel.api.converter.CellValueConverter;
import net.croz.nrich.excel.api.model.CellHolder;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.annotation.Order;

import java.math.BigDecimal;
Expand All @@ -36,11 +38,16 @@
import java.util.Optional;
import java.util.function.BiConsumer;

@RequiredArgsConstructor
@Order
public class DefaultCellValueConverter implements CellValueConverter {

private static final String ENUM_MESSAGE_FORMAT = "%s.%s.description";

private final List<ConverterHolder> converterHolderList = initializeConverterList();

private final MessageSource messageSource;

@Override
public void setCellValue(CellHolder cell, Object value) {
Optional.ofNullable(findConverter(value)).ifPresent(converterHolder -> converterHolder.setCellValueFunction.accept(cell, value));
Expand All @@ -65,7 +72,8 @@ private List<ConverterHolder> initializeConverterList() {
new ConverterHolder(Long.class, (cell, value) -> cell.setCellValue(((Number) value).longValue())),
new ConverterHolder(BigDecimal.class, (cell, value) -> cell.setCellValue(((Number) value).doubleValue())),
new ConverterHolder(Float.class, (cell, value) -> cell.setCellValue(((Number) value).doubleValue())),
new ConverterHolder(Double.class, (cell, value) -> cell.setCellValue(((Number) value).doubleValue()))
new ConverterHolder(Double.class, (cell, value) -> cell.setCellValue(((Number) value).doubleValue())),
new ConverterHolder(Enum.class, (cell, value) -> cell.setCellValue(resolveEnumValue(value)))
);
}

Expand All @@ -80,6 +88,11 @@ private ConverterHolder findConverter(Object value) {
.orElse(null);
}

private String resolveEnumValue(Object value) {
String messageCode = String.format(ENUM_MESSAGE_FORMAT, value.getClass().getName(), value);

return messageSource.getMessage(messageCode, null, value.toString(), LocaleContextHolder.getLocale());
}

@RequiredArgsConstructor
@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import net.croz.nrich.excel.generator.PoiExcelReportGeneratorFactory;
import net.croz.nrich.excel.service.DefaultExcelReportService;
import net.croz.nrich.excel.util.TypeDataFormatUtil;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.io.ResourceLoader;

import java.util.List;
Expand All @@ -35,8 +37,17 @@
public class ExcelTestConfiguration {

@Bean
public CellValueConverter defaultCellValueConverter() {
return new DefaultCellValueConverter();
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

messageSource.setBasename("messages");

return messageSource;
}

@Bean
public CellValueConverter defaultCellValueConverter(MessageSource messageSource) {
return new DefaultCellValueConverter(messageSource);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
package net.croz.nrich.excel.converter;

import net.croz.nrich.excel.api.model.CellHolder;
import net.croz.nrich.excel.stub.TestEnum;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.context.support.ResourceBundleMessageSource;

import java.math.BigDecimal;
import java.time.Instant;
Expand All @@ -41,7 +43,7 @@

class DefaultCellValueConverterTest {

private final DefaultCellValueConverter defaultCellValueConverter = new DefaultCellValueConverter();
private final DefaultCellValueConverter defaultCellValueConverter = new DefaultCellValueConverter(new ResourceBundleMessageSource());

@MethodSource("shouldReturnTrueIfConversionIsSupportedMethodSource")
@ParameterizedTest
Expand Down Expand Up @@ -73,7 +75,8 @@ private static Stream<Arguments> shouldReturnTrueIfConversionIsSupportedMethodSo
arguments(1L, true),
arguments(2.2F, true),
arguments(2.2D, true),
arguments(BigDecimal.ONE, true)
arguments(BigDecimal.ONE, true),
arguments(TestEnum.FIRST, true)
);
}

Expand Down Expand Up @@ -105,7 +108,8 @@ private static Stream<Arguments> shouldSetValueWithConversionIfNecessaryMethodSo
arguments(1L, Number.class),
arguments(2.2F, Number.class),
arguments(2.2D, Number.class),
arguments(BigDecimal.ONE, Number.class)
arguments(BigDecimal.ONE, Number.class),
arguments(TestEnum.FIRST, String.class)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
import net.croz.nrich.excel.api.model.TemplateVariable;
import net.croz.nrich.excel.api.model.TypeDataFormat;
import net.croz.nrich.excel.converter.DefaultCellValueConverter;
import net.croz.nrich.excel.stub.TestEnum;
import net.croz.nrich.excel.util.TypeDataFormatUtil;
import org.apache.poi.ss.usermodel.Sheet;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ResourceBundleMessageSource;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
Expand Down Expand Up @@ -63,7 +65,10 @@ class PoiExcelReportGeneratorTest {

@BeforeEach
void setup() {
List<CellValueConverter> cellValueConverterList = Collections.singletonList(new DefaultCellValueConverter());
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");

List<CellValueConverter> cellValueConverterList = Collections.singletonList(new DefaultCellValueConverter(messageSource));
InputStream template = this.getClass().getResourceAsStream("/excel/template.xlsx");
List<TemplateVariable> templateVariableList = Collections.singletonList(new TemplateVariable("templateVariable", "resolvedValue"));
List<ColumnDataFormat> columnDataFormatList = Arrays.asList(new ColumnDataFormat(2, "dd-MM-yyyy"), new ColumnDataFormat(3, "dd-MM-yyyy HH:mm"));
Expand All @@ -85,10 +90,10 @@ void shouldExportDataToExcel() {
Instant now = Instant.now().truncatedTo(ChronoUnit.DAYS);
Object[] rowData = new Object[] {
1.1, "value", new Date(now.toEpochMilli()), ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS), OffsetDateTime.now().truncatedTo(ChronoUnit.DAYS), now, now, 1, 1.5F, (short) 1,
LocalDate.now(), LocalDateTime.now().truncatedTo(ChronoUnit.DAYS), BigDecimal.valueOf(1.5), 10L, null
LocalDate.now(), LocalDateTime.now().truncatedTo(ChronoUnit.DAYS), BigDecimal.valueOf(1.5), 10L, TestEnum.FIRST, TestEnum.SECOND, null
};
// when resolving data from cells all dates are converted to instant, all decimal numbers are converted to double and all whole numbers are converted to integer
Object[] expectedRowData = new Object[] { 1.1, "value", now, now, now, now, now, 1, 1.5, 1, now, now, 1.5, 10, null };
Object[] expectedRowData = new Object[] { 1.1, "value", now, now, now, now, now, 1, 1.5, 1, now, now, 1.5, 10, "First", "SECOND", null };

// when
excelReportGenerator.writeRowData(rowData);
Expand Down
22 changes: 22 additions & 0 deletions nrich-excel/src/test/java/net/croz/nrich/excel/stub/TestEnum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020-2023 CROZ d.o.o, 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 net.croz.nrich.excel.stub;

public enum TestEnum {
FIRST, SECOND
}
1 change: 1 addition & 0 deletions nrich-excel/src/test/resources/messages.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
net.croz.nrich.excel.stub.TestEnum.FIRST.description=First

0 comments on commit cb1ee62

Please sign in to comment.