[github-25] support excel number trailing comma format - Thabks to Luca Martini for proving the patch
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1800975 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a0aa8807b5
commit
23567cd3a0
@ -687,6 +687,57 @@ public class DataFormatter implements Observer {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class InternalDecimalFormatWithScale extends Format {
|
||||||
|
|
||||||
|
private static final Pattern endsWithCommas = Pattern.compile("(,+)$");
|
||||||
|
private BigDecimal divider;
|
||||||
|
private static final BigDecimal ONE_THOUSAND = new BigDecimal(1000);
|
||||||
|
private final DecimalFormat df;
|
||||||
|
private static final String trimTrailingCommas(String s) {
|
||||||
|
return s.replaceAll(",+$", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public InternalDecimalFormatWithScale(String pattern, DecimalFormatSymbols symbols) {
|
||||||
|
df = new DecimalFormat(trimTrailingCommas(pattern), symbols);
|
||||||
|
setExcelStyleRoundingMode(df);
|
||||||
|
Matcher endsWithCommasMatcher = endsWithCommas.matcher(pattern);
|
||||||
|
if (endsWithCommasMatcher.find()) {
|
||||||
|
String commas = (endsWithCommasMatcher.group(1));
|
||||||
|
BigDecimal temp = BigDecimal.ONE;
|
||||||
|
for (int i = 0; i < commas.length(); ++i) {
|
||||||
|
temp = temp.multiply(ONE_THOUSAND);
|
||||||
|
}
|
||||||
|
divider = temp;
|
||||||
|
} else {
|
||||||
|
divider = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object scaleInput(Object obj) {
|
||||||
|
if (divider != null) {
|
||||||
|
if (obj instanceof BigDecimal) {
|
||||||
|
obj = ((BigDecimal) obj).divide(divider, RoundingMode.HALF_UP);
|
||||||
|
} else if (obj instanceof Double) {
|
||||||
|
obj = (Double) obj / divider.doubleValue();
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
obj = scaleInput(obj);
|
||||||
|
return df.format(obj, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseObject(String source, ParsePosition pos) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Format createNumberFormat(String formatStr, double cellValue) {
|
private Format createNumberFormat(String formatStr, double cellValue) {
|
||||||
String format = cleanFormatForNumber(formatStr);
|
String format = cleanFormatForNumber(formatStr);
|
||||||
DecimalFormatSymbols symbols = decimalSymbols;
|
DecimalFormatSymbols symbols = decimalSymbols;
|
||||||
@ -710,9 +761,7 @@ public class DataFormatter implements Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DecimalFormat df = new DecimalFormat(format, symbols);
|
return new InternalDecimalFormatWithScale(format, symbols);
|
||||||
setExcelStyleRoundingMode(df);
|
|
||||||
return df;
|
|
||||||
} catch(IllegalArgumentException iae) {
|
} catch(IllegalArgumentException iae) {
|
||||||
logger.log(POILogger.DEBUG, "Formatting failed for format " + formatStr + ", falling back", iae);
|
logger.log(POILogger.DEBUG, "Formatting failed for format " + formatStr + ", falling back", iae);
|
||||||
// the pattern could not be parsed correctly,
|
// the pattern could not be parsed correctly,
|
||||||
|
@ -821,6 +821,36 @@ public class TestDataFormatter {
|
|||||||
wb.close();
|
wb.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatWithTrailingDotsUS() {
|
||||||
|
DataFormatter dfUS = new DataFormatter(Locale.US);
|
||||||
|
assertEquals("1,000,000", dfUS.formatRawCellContents(1000000, -1, "#,##0"));
|
||||||
|
assertEquals("1,000", dfUS.formatRawCellContents(1000000, -1, "#,##0,"));
|
||||||
|
assertEquals("1", dfUS.formatRawCellContents(1000000, -1, "#,##0,,"));
|
||||||
|
assertEquals("1,000,000.0", dfUS.formatRawCellContents(1000000, -1, "#,##0.0"));
|
||||||
|
assertEquals("1,000.0", dfUS.formatRawCellContents(1000000, -1, "#,##0.0,"));
|
||||||
|
assertEquals("1.0", dfUS.formatRawCellContents(1000000, -1, "#,##0.0,,"));
|
||||||
|
assertEquals("1,000,000.00", dfUS.formatRawCellContents(1000000, -1, "#,##0.00"));
|
||||||
|
assertEquals("1,000.00", dfUS.formatRawCellContents(1000000, -1, "#,##0.00,"));
|
||||||
|
assertEquals("1.00", dfUS.formatRawCellContents(1000000, -1, "#,##0.00,,"));
|
||||||
|
assertEquals("1,000,000", dfUS.formatRawCellContents(1e24, -1, "#,##0,,,,,,"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatWithTrailingDotsOtherLocale() throws Exception {
|
||||||
|
DataFormatter dfIT = new DataFormatter(Locale.ITALY);
|
||||||
|
assertEquals("1.000.000", dfIT.formatRawCellContents(1000000, -1, "#,##0"));
|
||||||
|
assertEquals("1.000", dfIT.formatRawCellContents(1000000, -1, "#,##0,"));
|
||||||
|
assertEquals("1", dfIT.formatRawCellContents(1000000, -1, "#,##0,,"));
|
||||||
|
assertEquals("1.000.000,0", dfIT.formatRawCellContents(1000000, -1, "#,##0.0"));
|
||||||
|
assertEquals("1.000,0", dfIT.formatRawCellContents(1000000, -1, "#,##0.0,"));
|
||||||
|
assertEquals("1,0", dfIT.formatRawCellContents(1000000, -1, "#,##0.0,,"));
|
||||||
|
assertEquals("1.000.000,00", dfIT.formatRawCellContents(1000000, -1, "#,##0.00"));
|
||||||
|
assertEquals("1.000,00", dfIT.formatRawCellContents(1000000, -1, "#,##0.00,"));
|
||||||
|
assertEquals("1,00", dfIT.formatRawCellContents(1000000, -1, "#,##0.00,,"));
|
||||||
|
assertEquals("1.000.000", dfIT.formatRawCellContents(1e24, -1, "#,##0,,,,,,"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bug 60031: DataFormatter parses months incorrectly when put at the end of date segment
|
* bug 60031: DataFormatter parses months incorrectly when put at the end of date segment
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user