Browse Source

[Bug 60422] fix data formatter issue with specific format in German locale

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1800713 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_17_FINAL
PJ Fanning 7 years ago
parent
commit
26389768b9

+ 12
- 2
src/java/org/apache/poi/ss/format/CellDateFormatter.java View File

@@ -138,6 +138,16 @@ public class CellDateFormatter extends CellFormatter {
* @param format The format.
*/
public CellDateFormatter(String format) {
this(LocaleUtil.getUserLocale(), format);
}

/**
* Creates a new date formatter with the given specification.
*
* @param locale The locale.
* @param format The format.
*/
public CellDateFormatter(Locale locale, String format) {
super(format);
DatePartHandler partHandler = new DatePartHandler();
StringBuffer descBuf = CellFormatPart.parseFormat(format,
@@ -146,7 +156,7 @@ public class CellDateFormatter extends CellFormatter {
// tweak the format pattern to pass tests on JDK 1.7,
// See https://issues.apache.org/bugzilla/show_bug.cgi?id=53369
String ptrn = descBuf.toString().replaceAll("((y)(?!y))(?<!yy)", "yy");
dateFmt = new SimpleDateFormat(ptrn, LocaleUtil.getUserLocale());
dateFmt = new SimpleDateFormat(ptrn, locale);
dateFmt.setTimeZone(LocaleUtil.getUserTimeZone());
}

@@ -182,7 +192,7 @@ public class CellDateFormatter extends CellFormatter {
Formatter formatter = new Formatter(toAppendTo, Locale.ROOT);
try {
long msecs = dateObj.getTime() % 1000;
formatter.format(LocaleUtil.getUserLocale(), sFmt, msecs / 1000.0);
formatter.format(locale, sFmt, msecs / 1000.0);
} finally {
formatter.close();
}

+ 47
- 22
src/java/org/apache/poi/ss/format/CellFormat.java View File

@@ -20,6 +20,7 @@ package org.apache.poi.ss.format;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Level;
@@ -35,6 +36,7 @@ import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.util.DateFormatConverter;
import org.apache.poi.util.LocaleUtil;

/**
* Format a value according to the standard Excel behavior. This "standard" is
@@ -90,6 +92,7 @@ import org.apache.poi.ss.util.DateFormatConverter;
* native character numbers, as documented at https://help.libreoffice.org/Common/Number_Format_Codes
*/
public class CellFormat {
private final Locale locale;
private final String format;
private final CellFormatPart posNumFmt;
private final CellFormatPart zeroNumFmt;
@@ -101,9 +104,6 @@ public class CellFormat {
CellFormatPart.FORMAT_PAT.pattern() + "(;|$)",
Pattern.COMMENTS | Pattern.CASE_INSENSITIVE);

private static final CellFormatPart DEFAULT_TEXT_FORMAT =
new CellFormatPart("@");

/*
* Cells that cannot be formatted, e.g. cells that have a date or time
* format and have an invalid date or time value, are displayed as 255
@@ -121,18 +121,23 @@ public class CellFormat {
/**
* Format a value as it would be were no format specified. This is also
* used when the format specified is <tt>General</tt>.
* @deprecated use {@link #getInstance(Locale, "General")} instead
*/
public static final CellFormat GENERAL_FORMAT = new CellFormat("General") {
@Override
public CellFormatResult apply(Object value) {
String text = (new CellGeneralFormatter()).format(value);
return new CellFormatResult(true, text, null);
}
};
public static final CellFormat GENERAL_FORMAT = createGeneralFormat(LocaleUtil.getUserLocale());
private static CellFormat createGeneralFormat(final Locale locale) {
return new CellFormat(locale, "General") {
@Override
public CellFormatResult apply(Object value) {
String text = (new CellGeneralFormatter(locale)).format(value);
return new CellFormatResult(true, text, null);
}
};
}

/** Maps a format string to its parsed version for efficiencies sake. */
private static final Map<String, CellFormat> formatCache =
new WeakHashMap<String, CellFormat>();
private static final Map<Locale, Map<String, CellFormat>> formatCache =
new WeakHashMap<Locale, Map<String, CellFormat>>();

/**
* Returns a {@link CellFormat} that applies the given format. Two calls
@@ -143,13 +148,31 @@ public class CellFormat {
* @return A {@link CellFormat} that applies the given format.
*/
public static CellFormat getInstance(String format) {
CellFormat fmt = formatCache.get(format);
return getInstance(LocaleUtil.getUserLocale(), format);
}

/**
* Returns a {@link CellFormat} that applies the given format. Two calls
* with the same format may or may not return the same object.
*
* @param locale The locale.
* @param format The format.
*
* @return A {@link CellFormat} that applies the given format.
*/
public static synchronized CellFormat getInstance(Locale locale, String format) {
Map<String, CellFormat> formatMap = formatCache.get(locale);
if (formatMap == null) {
formatMap = new WeakHashMap<String, CellFormat>();
formatCache.put(locale, formatMap);
}
CellFormat fmt = formatMap.get(format);
if (fmt == null) {
if (format.equals("General") || format.equals("@"))
fmt = GENERAL_FORMAT;
fmt = createGeneralFormat(locale);
else
fmt = new CellFormat(format);
formatCache.put(format, fmt);
fmt = new CellFormat(locale, format);
formatMap.put(format, fmt);
}
return fmt;
}
@@ -159,8 +182,10 @@ public class CellFormat {
*
* @param format The format.
*/
private CellFormat(String format) {
private CellFormat(Locale locale, String format) {
this.locale = locale;
this.format = format;
CellFormatPart defaultTextFormat = new CellFormatPart(locale, "@");
Matcher m = ONE_PART.matcher(format);
List<CellFormatPart> parts = new ArrayList<CellFormatPart>();

@@ -172,7 +197,7 @@ public class CellFormat {
if (valueDesc.endsWith(";"))
valueDesc = valueDesc.substring(0, valueDesc.length() - 1);

parts.add(new CellFormatPart(valueDesc));
parts.add(new CellFormatPart(locale, valueDesc));
} catch (RuntimeException e) {
CellFormatter.logger.log(Level.WARNING,
"Invalid format: " + CellFormatter.quote(m.group()), e);
@@ -187,19 +212,19 @@ public class CellFormat {
posNumFmt = parts.get(0);
negNumFmt = null;
zeroNumFmt = null;
textFmt = DEFAULT_TEXT_FORMAT;
textFmt = defaultTextFormat;
break;
case 2:
posNumFmt = parts.get(0);
negNumFmt = parts.get(1);
zeroNumFmt = null;
textFmt = DEFAULT_TEXT_FORMAT;
textFmt = defaultTextFormat;
break;
case 3:
posNumFmt = parts.get(0);
negNumFmt = parts.get(1);
zeroNumFmt = parts.get(2);
textFmt = DEFAULT_TEXT_FORMAT;
textFmt = defaultTextFormat;
break;
case 4:
default:
@@ -384,7 +409,7 @@ public class CellFormat {
|| (posNumFmt.hasCondition() && posNumFmt.applies(val))) {
return posNumFmt;
} else {
return new CellFormatPart("General");
return new CellFormatPart(locale, "General");
}
} else if (formatPartCount == 2) {
if ((!posNumFmt.hasCondition() && val >= 0)

+ 14
- 3
src/java/org/apache/poi/ss/format/CellFormatPart.java View File

@@ -17,6 +17,7 @@
package org.apache.poi.ss.format;

import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.util.LocaleUtil;

import javax.swing.*;

@@ -173,6 +174,16 @@ public class CellFormatPart {
* @param desc The string to parse.
*/
public CellFormatPart(String desc) {
this(LocaleUtil.getUserLocale(), desc);
}
/**
* Create an object to represent a format part.
*
* @param locale The locale to use.
* @param desc The string to parse.
*/
public CellFormatPart(Locale locale, String desc) {
Matcher m = FORMAT_PAT.matcher(desc);
if (!m.matches()) {
throw new IllegalArgumentException("Unrecognized format: " + quote(
@@ -181,7 +192,7 @@ public class CellFormatPart {
color = getColor(m);
condition = getCondition(m);
type = getCellFormatType(m);
format = getFormatter(m);
format = getFormatter(locale, m);
}

/**
@@ -287,7 +298,7 @@ public class CellFormatPart {
*
* @return The formatter.
*/
private CellFormatter getFormatter(Matcher matcher) {
private CellFormatter getFormatter(Locale locale, Matcher matcher) {
String fdesc = matcher.group(SPECIFICATION_GROUP);
// For now, we don't support localised currencies, so simplify if there
@@ -305,7 +316,7 @@ public class CellFormatPart {
}
// Build a formatter for this simplified string
return type.formatter(fdesc);
return type.formatter(locale, fdesc);
}

/**

+ 30
- 2
src/java/org/apache/poi/ss/format/CellFormatType.java View File

@@ -17,6 +17,8 @@

package org.apache.poi.ss.format;

import java.util.Locale;

/**
* The different kinds of formats that the formatter understands.
*
@@ -26,11 +28,14 @@ public enum CellFormatType {

/** The general (default) format; also used for <tt>"General"</tt>. */
GENERAL {
boolean isSpecial(char ch) {
return false;
}
CellFormatter formatter(String pattern) {
return new CellGeneralFormatter();
}
boolean isSpecial(char ch) {
return false;
CellFormatter formatter(Locale locale, String pattern) {
return new CellGeneralFormatter(locale);
}
},
/** A numeric format. */
@@ -41,6 +46,9 @@ public enum CellFormatType {
CellFormatter formatter(String pattern) {
return new CellNumberFormatter(pattern);
}
CellFormatter formatter(Locale locale, String pattern) {
return new CellNumberFormatter(locale, pattern);
}
},
/** A date format. */
DATE {
@@ -50,6 +58,9 @@ public enum CellFormatType {
CellFormatter formatter(String pattern) {
return new CellDateFormatter(pattern);
}
CellFormatter formatter(Locale locale, String pattern) {
return new CellDateFormatter(locale, pattern);
}
},
/** An elapsed time format. */
ELAPSED {
@@ -59,6 +70,9 @@ public enum CellFormatType {
CellFormatter formatter(String pattern) {
return new CellElapsedFormatter(pattern);
}
CellFormatter formatter(Locale locale, String pattern) {
return new CellElapsedFormatter(pattern);
}
},
/** A text format. */
TEXT {
@@ -68,6 +82,9 @@ public enum CellFormatType {
CellFormatter formatter(String pattern) {
return new CellTextFormatter(pattern);
}
CellFormatter formatter(Locale locale, String pattern) {
return new CellTextFormatter(pattern);
}
};

/**
@@ -88,4 +105,15 @@ public enum CellFormatType {
* @return A new formatter of the appropriate type, for the given pattern.
*/
abstract CellFormatter formatter(String pattern);

/**
* Returns a new formatter of the appropriate type, for the given pattern.
* The pattern must be appropriate for the type.
*
* @param locale The locale to use.
* @param pattern The pattern to use.
*
* @return A new formatter of the appropriate type, for the given pattern.
*/
abstract CellFormatter formatter(Locale locale, String pattern);
}

+ 15
- 0
src/java/org/apache/poi/ss/format/CellFormatter.java View File

@@ -16,8 +16,11 @@
==================================================================== */
package org.apache.poi.ss.format;

import java.util.Locale;
import java.util.logging.Logger;

import org.apache.poi.util.LocaleUtil;

/**
* This is the abstract supertype for the various cell formatters.
*
@@ -26,6 +29,7 @@ import java.util.logging.Logger;
public abstract class CellFormatter {
/** The original specified format. */
protected final String format;
protected final Locale locale;

/**
* Creates a new formatter object, storing the format in {@link #format}.
@@ -33,6 +37,17 @@ public abstract class CellFormatter {
* @param format The format.
*/
public CellFormatter(String format) {
this(LocaleUtil.getUserLocale(), format);
}

/**
* Creates a new formatter object, storing the format in {@link #format}.
*
* @param locale The locale.
* @param format The format.
*/
public CellFormatter(Locale locale, String format) {
this.locale = locale;
this.format = format;
}


+ 7
- 3
src/java/org/apache/poi/ss/format/CellGeneralFormatter.java View File

@@ -29,7 +29,11 @@ import org.apache.poi.util.LocaleUtil;
public class CellGeneralFormatter extends CellFormatter {
/** Creates a new general formatter. */
public CellGeneralFormatter() {
super("General");
this(LocaleUtil.getUserLocale());
}
/** Creates a new general formatter. */
public CellGeneralFormatter(Locale locale) {
super(locale, "General");
}

/**
@@ -59,9 +63,9 @@ public class CellGeneralFormatter extends CellFormatter {
stripZeros = false;
}

Formatter formatter = new Formatter(toAppendTo, LocaleUtil.getUserLocale());
Formatter formatter = new Formatter(toAppendTo, locale);
try {
formatter.format(LocaleUtil.getUserLocale(), fmt, value);
formatter.format(locale, fmt, value);
} finally {
formatter.close();
}

+ 72
- 30
src/java/org/apache/poi/ss/format/CellNumberFormatter.java View File

@@ -26,6 +26,7 @@ import java.util.Formatter;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;

@@ -48,7 +49,7 @@ public class CellNumberFormatter extends CellFormatter {
private final Special numerator;
private final Special afterInteger;
private final Special afterFractional;
private final boolean integerCommas;
private final boolean showGroupingSeparator;
private final List<Special> specials = new ArrayList<Special>();
private final List<Special> integerSpecials = new ArrayList<Special>();
private final List<Special> fractionalSpecials = new ArrayList<Special>();
@@ -69,13 +70,11 @@ public class CellNumberFormatter extends CellFormatter {
// ("#" for integer values, and "#.#" for floating-point values) is
// different from the 'General' format for numbers ("#" for integer
// values and "#.#########" for floating-point values).
private static final CellFormatter SIMPLE_NUMBER = new GeneralNumberFormatter();
private static final CellFormatter SIMPLE_INT = new CellNumberFormatter("#");
private static final CellFormatter SIMPLE_FLOAT = new CellNumberFormatter("#.#");
private final CellFormatter SIMPLE_NUMBER = new GeneralNumberFormatter(locale);

private static class GeneralNumberFormatter extends CellFormatter {
private GeneralNumberFormatter() {
super("General");
private GeneralNumberFormatter(Locale locale) {
super(locale, "General");
}

public void formatValue(StringBuffer toAppendTo, Object value) {
@@ -86,7 +85,8 @@ public class CellNumberFormatter extends CellFormatter {
CellFormatter cf;
if (value instanceof Number) {
Number num = (Number) value;
cf = (num.doubleValue() % 1.0 == 0) ? SIMPLE_INT : SIMPLE_FLOAT;
cf = (num.doubleValue() % 1.0 == 0) ? new CellNumberFormatter(locale, "#") :
new CellNumberFormatter(locale, "#.#");
} else {
cf = CellTextFormatter.SIMPLE_TEXT;
}
@@ -124,7 +124,17 @@ public class CellNumberFormatter extends CellFormatter {
* @param format The format to parse.
*/
public CellNumberFormatter(String format) {
super(format);
this(LocaleUtil.getUserLocale(), format);
}

/**
* Creates a new cell number formatter.
*
* @param locale The locale to use.
* @param format The format to parse.
*/
public CellNumberFormatter(Locale locale, String format) {
super(locale, format);

CellNumberPartHandler ph = new CellNumberPartHandler();
StringBuffer descBuf = CellFormatPart.parseFormat(format, CellFormatType.NUMBER, ph);
@@ -177,7 +187,7 @@ public class CellNumberFormatter extends CellFormatter {
}
double scaleByRef[] = { ph.getScale() };
integerCommas = interpretIntegerCommas(descBuf, specials, decimalPoint, integerEnd(), fractionalEnd(), scaleByRef);
showGroupingSeparator = interpretIntegerCommas(descBuf, specials, decimalPoint, integerEnd(), fractionalEnd(), scaleByRef);
if (exponent == null) {
scale = scaleByRef[0];
} else {
@@ -259,14 +269,17 @@ public class CellNumberFormatter extends CellFormatter {
}
fmtBuf.append('E');
placeZeros(fmtBuf, exponentSpecials.subList(2, exponentSpecials.size()));
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(LocaleUtil.getUserLocale());
decimalFmt = new DecimalFormat(fmtBuf.toString(), dfs);
decimalFmt = new DecimalFormat(fmtBuf.toString(), getDecimalFormatSymbols());
printfFmt = null;
}

desc = descBuf.toString();
}

private DecimalFormatSymbols getDecimalFormatSymbols() {
return DecimalFormatSymbols.getInstance(locale);
}
private static void placeZeros(StringBuffer sb, List<Special> specials) {
for (Special s : specials) {
if (isDigitFmt(s)) {
@@ -436,7 +449,7 @@ public class CellNumberFormatter extends CellFormatter {
}

Set<CellNumberStringMod> mods = new TreeSet<CellNumberStringMod>();
StringBuffer output = new StringBuffer(desc);
StringBuffer output = new StringBuffer(localiseFormat(desc));

if (exponent != null) {
writeScientific(value, output, mods);
@@ -444,21 +457,24 @@ public class CellNumberFormatter extends CellFormatter {
writeFraction(value, null, fractional, output, mods);
} else {
StringBuffer result = new StringBuffer();
Formatter f = new Formatter(result, LocaleUtil.getUserLocale());
Formatter f = new Formatter(result, locale);
try {
f.format(LocaleUtil.getUserLocale(), printfFmt, value);
f.format(locale, printfFmt, value);
} finally {
f.close();
}

if (numerator == null) {
writeFractional(result, output);
writeInteger(result, output, integerSpecials, mods, integerCommas);
writeInteger(result, output, integerSpecials, mods, showGroupingSeparator);
} else {
writeFraction(value, result, fractional, output, mods);
}
}

DecimalFormatSymbols dfs = getDecimalFormatSymbols();
String groupingSeparator = Character.toString(dfs.getGroupingSeparator());

// Now strip out any remaining '#'s and add any pending text ...
Iterator<CellNumberStringMod> changes = mods.iterator();
CellNumberStringMod nextChange = (changes.hasNext() ? changes.next() : null);
@@ -478,7 +494,7 @@ public class CellNumberFormatter extends CellFormatter {
switch (nextChange.getOp()) {
case CellNumberStringMod.AFTER:
// ignore adding a comma after a deleted char (which was a '#')
if (nextChange.getToAdd().equals(",") && deletedChars.get(s.pos)) {
if (nextChange.getToAdd().equals(groupingSeparator) && deletedChars.get(s.pos)) {
break;
}
output.insert(modPos + 1, nextChange.getToAdd());
@@ -545,7 +561,7 @@ public class CellNumberFormatter extends CellFormatter {
StringBuffer result = new StringBuffer();
FieldPosition fractionPos = new FieldPosition(DecimalFormat.FRACTION_FIELD);
decimalFmt.format(value, result, fractionPos);
writeInteger(result, output, integerSpecials, mods, integerCommas);
writeInteger(result, output, integerSpecials, mods, showGroupingSeparator);
writeFractional(result, output);

/*
@@ -683,6 +699,27 @@ public class CellNumberFormatter extends CellFormatter {
LOG.log(POILogger.ERROR, "error while fraction evaluation", ignored);
}
}
private String localiseFormat(String format) {
DecimalFormatSymbols dfs = getDecimalFormatSymbols();
if(format.contains(",") && dfs.getGroupingSeparator() != ',') {
if(format.contains(".") && dfs.getDecimalSeparator() != '.') {
format = replaceLast(format, "\\.", "[DECIMAL_SEPARATOR]");
format = format.replace(',', dfs.getGroupingSeparator())
.replace("[DECIMAL_SEPARATOR]", Character.toString(dfs.getDecimalSeparator()));
} else {
format = format.replace(',', dfs.getGroupingSeparator());
}
} else if(format.contains(".") && dfs.getDecimalSeparator() != '.') {
format = format.replace('.', dfs.getDecimalSeparator());
}
return format;
}
private static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)(.*)" + regex, "$1" + replacement);
}

private static boolean hasChar(char ch, List<Special>... numSpecials) {
for (List<Special> specials : numSpecials) {
@@ -698,9 +735,9 @@ public class CellNumberFormatter extends CellFormatter {
private void writeSingleInteger(String fmt, int num, StringBuffer output, List<Special> numSpecials, Set<CellNumberStringMod> mods) {

StringBuffer sb = new StringBuffer();
Formatter formatter = new Formatter(sb, LocaleUtil.getUserLocale());
Formatter formatter = new Formatter(sb, locale);
try {
formatter.format(LocaleUtil.getUserLocale(), fmt, num);
formatter.format(locale, fmt, num);
} finally {
formatter.close();
}
@@ -709,9 +746,13 @@ public class CellNumberFormatter extends CellFormatter {

private void writeInteger(StringBuffer result, StringBuffer output,
List<Special> numSpecials, Set<CellNumberStringMod> mods,
boolean showCommas) {
boolean showGroupingSeparator) {

DecimalFormatSymbols dfs = getDecimalFormatSymbols();
String decimalSeparator = Character.toString(dfs.getDecimalSeparator());
String groupingSeparator = Character.toString(dfs.getGroupingSeparator());

int pos = result.indexOf(".") - 1;
int pos = result.indexOf(decimalSeparator) - 1;
if (pos < 0) {
if (exponent != null && numSpecials == integerSpecials) {
pos = result.indexOf("E") - 1;
@@ -723,13 +764,13 @@ public class CellNumberFormatter extends CellFormatter {
int strip;
for (strip = 0; strip < pos; strip++) {
char resultCh = result.charAt(strip);
if (resultCh != '0' && resultCh != ',') {
if (resultCh != '0' && resultCh != dfs.getGroupingSeparator()) {
break;
}
}

ListIterator<Special> it = numSpecials.listIterator(numSpecials.size());
boolean followWithComma = false;
boolean followWithGroupingSeparator = false;
Special lastOutputIntegerDigit = null;
int digit = 0;
while (it.hasPrevious()) {
@@ -741,16 +782,16 @@ public class CellNumberFormatter extends CellFormatter {
resultCh = '0';
}
Special s = it.previous();
followWithComma = showCommas && digit > 0 && digit % 3 == 0;
followWithGroupingSeparator = showGroupingSeparator && digit > 0 && digit % 3 == 0;
boolean zeroStrip = false;
if (resultCh != '0' || s.ch == '0' || s.ch == '?' || pos >= strip) {
zeroStrip = s.ch == '?' && pos < strip;
output.setCharAt(s.pos, (zeroStrip ? ' ' : resultCh));
lastOutputIntegerDigit = s;
}
if (followWithComma) {
mods.add(insertMod(s, zeroStrip ? " " : ",", CellNumberStringMod.AFTER));
followWithComma = false;
if (followWithGroupingSeparator) {
mods.add(insertMod(s, zeroStrip ? " " : groupingSeparator, CellNumberStringMod.AFTER));
followWithGroupingSeparator = false;
}
digit++;
--pos;
@@ -761,10 +802,10 @@ public class CellNumberFormatter extends CellFormatter {
// pos was decremented at the end of the loop above when the iterator was at its end
++pos;
extraLeadingDigits = new StringBuffer(result.substring(0, pos));
if (showCommas) {
if (showGroupingSeparator) {
while (pos > 0) {
if (digit > 0 && digit % 3 == 0) {
extraLeadingDigits.insert(pos, ',');
extraLeadingDigits.insert(pos, groupingSeparator);
}
digit++;
--pos;
@@ -778,7 +819,8 @@ public class CellNumberFormatter extends CellFormatter {
int digit;
int strip;
if (fractionalSpecials.size() > 0) {
digit = result.indexOf(".") + 1;
String decimalSeparator = Character.toString(getDecimalFormatSymbols().getDecimalSeparator());
digit = result.indexOf(decimalSeparator) + 1;
if (exponent != null) {
strip = result.indexOf("e") - 1;
} else {

+ 9
- 13
src/java/org/apache/poi/ss/usermodel/DataFormatter.java View File

@@ -292,10 +292,6 @@ public class DataFormatter implements Observer {
* @param cell The cell to retrieve a Format for
* @return A Format for the format String
*/
private Format getFormat(Cell cell) {
return getFormat(cell, null);
}
private Format getFormat(Cell cell, ConditionalFormattingEvaluator cfEvaluator) {
if (cell == null) return null;
@@ -315,12 +311,12 @@ public class DataFormatter implements Observer {

private Format getFormat(double cellValue, int formatIndex, String formatStrIn) {
localeChangedObservable.checkForLocaleChange();
// // Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
// // That however would require other code to be re factored.
// String[] formatBits = formatStrIn.split(";");
// int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2;
// String formatStr = (i < formatBits.length) ? formatBits[i] : formatBits[0];
// Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
// That however would require other code to be re factored.
// String[] formatBits = formatStrIn.split(";");
// int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2;
// String formatStr = (i < formatBits.length) ? formatBits[i] : formatBits[0];

String formatStr = formatStrIn;
@@ -336,7 +332,7 @@ public class DataFormatter implements Observer {
) ) {
try {
// Ask CellFormat to get a formatter for it
CellFormat cfmt = CellFormat.getInstance(formatStr);
CellFormat cfmt = CellFormat.getInstance(locale, formatStr);
// CellFormat requires callers to identify date vs not, so do so
Object cellValueO = Double.valueOf(cellValue);
if (DateUtil.isADateFormat(formatIndex, formatStr) &&
@@ -607,7 +603,7 @@ public class DataFormatter implements Observer {
try {
return new ExcelStyleDateFormatter(formatStr, dateSymbols);
} catch(IllegalArgumentException iae) {
logger.log(POILogger.DEBUG, "Formatting failed for format " + formatStr + ", falling back", iae);
// the pattern could not be parsed correctly,
// so fall back to the default number format
return getDefaultFormat(cellValue);
@@ -718,7 +714,7 @@ public class DataFormatter implements Observer {
setExcelStyleRoundingMode(df);
return df;
} catch(IllegalArgumentException iae) {
logger.log(POILogger.DEBUG, "Formatting failed for format " + formatStr + ", falling back", iae);
// the pattern could not be parsed correctly,
// so fall back to the default number format
return getDefaultFormat(cellValue);

+ 7
- 14
src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java View File

@@ -811,7 +811,6 @@ public class TestDataFormatter {
CellReference ref = new CellReference("D47");

Cell cell = wb.getSheetAt(0).getRow(ref.getRow()).getCell(ref.getCol());
//noinspection deprecation
assertEquals(CellType.FORMULA, cell.getCellTypeEnum());
assertEquals("G9:K9 I7:I12", cell.getCellFormula());

@@ -888,18 +887,12 @@ public class TestDataFormatter {
≈ */
@Test
public void testBug60422() {
//when this is set to Locale.Germany, the result is
LocaleUtil.setUserLocale(Locale.ROOT);
try {
char euro = '\u20AC';
DataFormatter df = new DataFormatter(Locale.GERMANY);
String formatString = String.format(Locale.ROOT,
"_-* #,##0.00\\ \"%s\"_-;\\-* #,##0.00\\ \"%s\"_-;_-* \"-\"??\\ \"%s\"_-;_-@_-",
euro, euro, euro);
//this should be 4,33
assertEquals("4.33 " + euro, df.formatRawCellContents(4.33, 178, formatString));
} finally {
LocaleUtil.resetUserLocale();
}
char euro = '\u20AC';
DataFormatter df = new DataFormatter(Locale.GERMANY);
String formatString = String.format(Locale.ROOT,
"_-* #,##0.00\\ \"%s\"_-;\\-* #,##0.00\\ \"%s\"_-;_-* \"-\"??\\ \"%s\"_-;_-@_-",
euro, euro, euro);
assertEquals("4,33 " + euro, df.formatRawCellContents(4.33, 178, formatString));
assertEquals("1.234,33 " + euro, df.formatRawCellContents(1234.33, 178, formatString));
}
}

Loading…
Cancel
Save