From 6de1dc574e261c9bc1b9bec4989dc85fc08f9e2a Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 12 Jun 2012 22:10:52 +0000 Subject: [PATCH] Fix bug #53389 - Handle formatting General and @ formats even if a locale is prefixed to them git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1349562 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../poi/ss/usermodel/DataFormatter.java | 25 +++++++++++++++---- .../poi/ss/usermodel/TestDataFormatter.java | 18 +++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index b2c7083a8..e605f9ee6 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53389 - Handle formatting General and @ formats even if a locale is prefixed to them 53271 - Removed unconditional asserts in SXSSF 53025 - Updatad documentation and example on using Data Validations 53227 - Corrected AddDimensionedImage.java to support XSSF/SXSSF diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 3f09aafa2..cfa20914f 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -111,8 +111,11 @@ public class DataFormatter { /** Pattern to find "AM/PM" marker */ private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE); - /** A regex to find patterns like [$$-1009] and [$?-452]. */ - private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); + /** + * A regex to find locale patterns like [$$-1009] and [$?-452]. + * Note that we don't currently process these into locales + */ + private static final Pattern localePatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); /** * A regex to match the colour formattings rules. @@ -278,12 +281,16 @@ public class DataFormatter { if (format != null) { return format; } + + // Is it one of the special built in types, General or @? if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) { if (isWholeNumber(cellValue)) { return generalWholeNumFormat; } return generalDecimalNumFormat; } + + // Build a formatter, and cache it format = createFormat(cellValue, formatIndex, formatStr); formats.put(formatStr, format); return format; @@ -323,8 +330,8 @@ public class DataFormatter { colourM = colorPattern.matcher(formatStr); } - // try to extract special characters like currency - Matcher m = specialPatternGroup.matcher(formatStr); + // Strip off the locale information, we use an instance-wide locale for everything + Matcher m = localePatternGroup.matcher(formatStr); while(m.find()) { String match = m.group(); String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-')); @@ -336,12 +343,20 @@ public class DataFormatter { symbol = sb.toString(); } formatStr = m.replaceAll(symbol); - m = specialPatternGroup.matcher(formatStr); + m = localePatternGroup.matcher(formatStr); } + // Check for special cases if(formatStr == null || formatStr.trim().length() == 0) { return getDefaultFormat(cellValue); } + + if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) { + if (isWholeNumber(cellValue)) { + return generalWholeNumFormat; + } + return generalDecimalNumFormat; + } if(DateUtil.isADateFormat(formatIndex,formatStr) && DateUtil.isValidExcelDate(cellValue)) { diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java index 499fe5442..b8c3a78a2 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -46,6 +46,24 @@ public class TestDataFormatter extends TestCase { assertEquals("12,34", dfFR.formatRawCellContents(12.34, -1, "@")); } + /** + * At the moment, we don't decode the locale strings into + * a specific locale, but we should format things as if + * the locale (eg '[$-1010409]') isn't there + */ + public void testLocaleBasedFormats() { + DataFormatter dfUS = new DataFormatter(Locale.US); + + // Standard formats + assertEquals("63", dfUS.formatRawCellContents(63.0, -1, "[$-1010409]General")); + assertEquals("63", dfUS.formatRawCellContents(63.0, -1, "[$-1010409]@")); + + // Regular numeric style formats + assertEquals("63", dfUS.formatRawCellContents(63.0, -1, "[$-1010409]##")); + assertEquals("63", dfUS.formatRawCellContents(63.0, -1, "[$-1010409]00")); + + } + /** * Ensure that colours get correctly * zapped from within the format strings