Skip to content

Commit

Permalink
Merge 398d2e1 into eaf1a04
Browse files Browse the repository at this point in the history
  • Loading branch information
ozlerhakan committed Dec 27, 2020
2 parents eaf1a04 + 398d2e1 commit 6f0519b
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 15 deletions.
23 changes: 20 additions & 3 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
:toclevels: 1

= Poiji
:version: v3.0.2
:version: v3.0.3


image:https://travis-ci.org/ozlerhakan/poiji.svg?branch=master["Build Status", link="https://travis-ci.org/ozlerhakan/poiji"] image:https://api.codacy.com/project/badge/Grade/6587e90886184da29a1b7c5634695c9d["Codacy code quality", link="https://www.codacy.com/app/ozlerhakan/poiji?utm_source=github.com&utm_medium=referral&utm_content=ozlerhakan/poiji&utm_campaign=Badge_Grade"] image:https://coveralls.io/repos/github/ozlerhakan/poiji/badge.svg?branch=master["Coverage Status", link="https://coveralls.io/github/ozlerhakan/poiji?branch=master"] image:https://img.shields.io/badge/apache.poi-4.1.2-brightgreen.svg[] image:https://app.fossa.com/api/projects/git%2Bgithub.com%2Fozlerhakan%2Fpoiji.svg?type=shield["FOSSA Status", link="https://app.fossa.com/projects/git%2Bgithub.com%2Fozlerhakan%2Fpoiji?ref=badge_shield"] image:https://img.shields.io/badge/license-MIT-blue.svg[]
Expand All @@ -23,15 +23,15 @@ In your Maven/Gradle project, first add the corresponding dependency:
<dependency>
<groupId>com.github.ozlerhakan</groupId>
<artifactId>poiji</artifactId>
<version>3.0.2</version>
<version>3.0.3</version>
</dependency>
----

.gradle
[source,groovy]
----
dependencies {
compile 'com.github.ozlerhakan:poiji:3.0.2'
compile 'com.github.ozlerhakan:poiji:3.0.3'
}
----

Expand Down Expand Up @@ -83,6 +83,7 @@ com.poiji.option.PoijiOptions.PoijiOptionsBuilder#poijiNumberFormat(PoijiNumberF
com.poiji.option.PoijiOptions.PoijiOptionsBuilder#poijiLogCellFormat(PoijiLogCellFormat)
com.poiji.option.PoijiOptions.PoijiOptionsBuilder#disableXLSXNumberCellFormat()
com.poiji.option.PoijiOptions.PoijiOptionsBuilder#addListDelimiter(String)
com.poiji.option.PoijiOptions.PoijiOptionsBuilder#setLocale(java.util.Locale)
----

=== Feature 1
Expand Down Expand Up @@ -821,6 +822,22 @@ Sheet sheet = workbook.getSheetAt(0);
List<Model> result = Poiji.fromExcel(sheet, Model.class);
----

=== Feature 17

For parsing numbers and dates java.lang.Locale is used. Also Apache Poi uses the Locale for parsing.
As default, Poij uses Locale.US irrespective of Locale used on the running system. If you want to change that
you can use a option to pass the Locale to be used like shown below.

In this example the Jvm default locale is used. Beware that if your code run's on a other Jvm with another Locale set as default parsing could give different results. Better is to use a fixed locale.
Also be aware of differences how Locales behave between Java 8 and 9+. For example AM/PM in Locale.GERMANY is displayed as AM/PM in Java 8 but Vorn./Nam. in Java 9 or higher.
This is due to the changes in Java 9. See https://openjdk.java.net/jeps/252[JEP-252] for more details.

[source,java]
----
PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings()
.setLocale(Locale.getDefault())
.build();
----
== Stargazers over time

image:https://starcharts.herokuapp.com/ozlerhakan/poiji.svg["Stargazers over time", link="https://starcharts.herokuapp.com/ozlerhakan/poiji"]
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.ozlerhakan</groupId>
<artifactId>poiji</artifactId>
<version>3.0.2</version>
<version>3.0.3</version>
<packaging>jar</packaging>

<name>poiji</name>
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/com/poiji/config/DefaultCasting.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,33 +98,33 @@ private Long longValue(String value, String sheetName, int row, int col, PoijiOp
}
}

private double primitiveDoubleValue(String value, String sheetName, int row, int col) {
private double primitiveDoubleValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return Parsers.numbers().parse(value).doubleValue();
return Parsers.numbers(options.getLocale()).parse(value).doubleValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0d);
}
}

private Double doubleValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return Parsers.numbers().parse(value).doubleValue();
return Parsers.numbers(options.getLocale()).parse(value).doubleValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0d);
}
}

private float primitiveFloatValue(String value, String sheetName, int row, int col) {
private float primitiveFloatValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return Parsers.numbers().parse(value).floatValue();
return Parsers.numbers(options.getLocale()).parse(value).floatValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, 0f);
}
}

private Float floatValue(String value, String sheetName, int row, int col, PoijiOptions options) {
try {
return Parsers.numbers().parse(value).floatValue();
return Parsers.numbers(options.getLocale()).parse(value).floatValue();
} catch (NumberFormatException nfe) {
return onError(value, sheetName, row, col, nfe, options.preferNullOverDefault() ? null : 0f);
}
Expand Down Expand Up @@ -274,7 +274,7 @@ protected Object getValueObject(Field field, int row, int col, PoijiOptions opti
o = longValue(value, sheetName, row, col, options);

} else if (fieldType == double.class) {
o = primitiveDoubleValue(value, sheetName, row, col);
o = primitiveDoubleValue(value, sheetName, row, col, options);

} else if (fieldType == Double.class) {
o = doubleValue(value, sheetName, row, col, options);
Expand All @@ -286,7 +286,7 @@ protected Object getValueObject(Field field, int row, int col, PoijiOptions opti
o = booleanValue(value, sheetName, row, col, options);

} else if (fieldType == float.class) {
o = primitiveFloatValue(value, sheetName, row, col);
o = primitiveFloatValue(value, sheetName, row, col, options);

} else if (fieldType == Float.class) {
o = floatValue(value, sheetName, row, col, options);
Expand Down
29 changes: 28 additions & 1 deletion src/main/java/com/poiji/option/PoijiOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import com.poiji.config.DefaultFormatting;
import com.poiji.config.Formatting;
import com.poiji.exception.PoijiException;
import org.apache.poi.util.LocaleUtil;

import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Objects;

import static com.poiji.util.PoijiConstants.DEFAULT_DATE_FORMATTER;
Expand Down Expand Up @@ -46,6 +48,7 @@ public final class PoijiOptions {
private boolean disableXLSXNumberCellFormat;
private String listDelimiter;
private Formatting formatting;
private Locale locale;

public PoijiNumberFormat getPoijiNumberFormat() {
return numberFormat;
Expand Down Expand Up @@ -281,6 +284,16 @@ private PoijiOptions setFormatting(Formatting formatting) {
return this;
}

public Locale getLocale() {
return this.locale;
}

private PoijiOptions setLocale(Locale locale) {
this.locale = locale;
LocaleUtil.setUserLocale(locale);
return this;
}

public static class PoijiOptionsBuilder {

private int sheetIndex;
Expand Down Expand Up @@ -308,6 +321,7 @@ public static class PoijiOptionsBuilder {
private boolean namedHeaderMandatory;
private boolean disabledXLSXNumberCellFormat;
private String listDelimiter = ",";
private Locale locale = Locale.US;

private PoijiOptionsBuilder() {
}
Expand Down Expand Up @@ -381,6 +395,18 @@ public PoijiOptionsBuilder preferNullOverDefault(boolean preferNullOverDefault)
return this;
}

/**
* Set the {@link Locale} used by Apache Poi and PoiJ. Default is {@link Locale#ENGLISH}.
* This setting is only used by Apache Poi thread and PoiJ. See {@link org.apache.poi.util.LocaleUtil}
* for more details.
* @param locale Locale
* @return this
*/
public PoijiOptionsBuilder setLocale(Locale locale) {
this.locale = locale;
return this;
}

public PoijiOptions build() {
return new PoijiOptions()
.setSkip(skip + headerStart + headerCount - 1)
Expand All @@ -407,7 +433,8 @@ public PoijiOptions build() {
.setNamedHeaderMandatory(namedHeaderMandatory)
.disableXLSXNumberCellFormat(disabledXLSXNumberCellFormat)
.setListDelimiter(listDelimiter)
.setFormatting(formatting);
.setFormatting(formatting)
.setLocale(locale);
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/poiji/parser/Parsers.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.poiji.parser;

import com.poiji.option.PoijiOptions;

import java.text.NumberFormat;
import java.util.Locale;

/**
* @see <a href="https://www.ibm.com/developerworks/library/j-numberformat/index.html">Resolving NumberFormat's parsing issues</a>
Expand All @@ -25,8 +28,8 @@ public static BigDecimalParser bigDecimals() {
return new BigDecimalParser();
}

public static NumberParser numbers() {
return new NumberParser(NumberFormat.getInstance());
public static NumberParser numbers(Locale locale) {
return new NumberParser(NumberFormat.getInstance(locale));
}

public static BooleanParser booleans() {
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/com/poiji/deserialize/DeserializerCaseDateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -66,4 +70,40 @@ public void shouldMapExcelToJava() {
fail(e.getMessage());
}
}

@Test
public void shouldMapExcelToJavaWithNonDefaultLocale() {
Locale userLocale = Locale.GERMANY;
try (InputStream stream = new FileInputStream(new File(path))) {
PoijiNumberFormat numberFormat = new PoijiNumberFormat();
numberFormat.putNumberFormat((short) 47, "mm/dd/yyyy hh.mm aa");
numberFormat.putNumberFormat((short) 22, "mm/dd/yyyy hh.mm aa");

PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings()
.poijiNumberFormat(numberFormat)
.setLocale(userLocale)
.build();

List<DateExcelColumn> rows = Poiji.fromExcel(stream, poijiExcelType, DateExcelColumn.class, options);

DateExcelColumn row = rows.get(0);

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh.mm aa", userLocale);
Calendar calendar = Calendar.getInstance();
calendar.set(2020, 11,31, 0, 00);
String expectedValueCol1 = sdf.format(calendar.getTime());
calendar.set(2015, 10,9, 0, 00);
String expectedValueCol2And3 = sdf.format(calendar.getTime());


assertThat(row.getDate1(), is(expectedValueCol1));
assertThat(row.getDate2(), is(expectedValueCol2And3));
assertThat(row.getDate3(), is(expectedValueCol2And3));

assertThat(numberFormat.getNumberFormatAt((short) 47), is("mm/dd/yyyy hh.mm aa"));
assertThat(numberFormat.getNumberFormatAt((short) 22), is("mm/dd/yyyy hh.mm aa"));
} catch (IOException e) {
fail(e.getMessage());
}
}
}
19 changes: 19 additions & 0 deletions src/test/java/com/poiji/deserialize/PoijiOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.poiji.exception.PoijiException;
import com.poiji.option.PoijiOptions;
import org.apache.poi.util.LocaleUtil;
import org.junit.Test;

import java.time.format.DateTimeFormatter;
import java.util.Locale;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -41,4 +43,21 @@ public void shouldPrintDateTimeFormatter() {
PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings().dateFormatter(formatter).build();
assertThat(options.dateFormatter().toString(), equalTo(formatter.toString()));
}

@Test
public void shouldUseUsLocaleWhenNotSpecified() {
PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings().build();

assertThat(options.getLocale(), equalTo(Locale.US));
assertThat(LocaleUtil.getUserLocale(), equalTo(Locale.US));
}

@Test
public void shouldUseProvidedLocaleWhenSpecified() {
Locale userLocale = Locale.GERMAN;
PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings().setLocale(userLocale).build();

assertThat(options.getLocale(), equalTo(userLocale));
assertThat(LocaleUtil.getUserLocale(), equalTo(userLocale));
}
}
17 changes: 17 additions & 0 deletions src/test/java/com/poiji/util/DecimalSeparatorParseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ public void testLocaleSwitzerland() {
parseAndVerify();
}

@Test
public void testCustomLocaleSet() {
InputStream inputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(FILENAME);
PoijiOptions options = PoijiOptions.PoijiOptionsBuilder.settings()
.preferNullOverDefault(true)
.setLocale(Locale.GERMANY)
.build();

List<Row> parsedRows = Poiji.fromExcel(inputStream, PoijiExcelType.XLSX, Row.class, options);

assertThat(parsedRows.size(), is(3));
assertThat(parsedRows.get(0).decimalNumber, is(1.5));
assertThat(parsedRows.get(1).decimalNumber, is(1000.0));
assertThat(parsedRows.get(2).decimalNumber, is(123456.79));
}

private void parseAndVerify() {
InputStream inputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(FILENAME);
Expand Down

0 comments on commit 6f0519b

Please sign in to comment.