]> source.dussan.org Git - poi.git/commitdiff
Add patch from Jukka from bug #48617 + test - Optionally allow the overriding of...
authorNick Burch <nick@apache.org>
Tue, 26 Jan 2010 16:21:17 +0000 (16:21 +0000)
committerNick Burch <nick@apache.org>
Tue, 26 Jan 2010 16:21:17 +0000 (16:21 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@903303 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java
src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java
src/java/org/apache/poi/ss/usermodel/DataFormatter.java
src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java [new file with mode: 0644]

index 79da11ad8213c51a5cd4268d020140278ca95d98..b0ae08f9b9f098af6df041ce7e483d3d843f15fd 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="add">48617 - Optionally allow the overriding of the Locale used by DataFormatter to control how the default number and date formats should look</action>
            <action dev="POI-DEVELOPERS" type="add">New event based xssf text extractor (XSSFEventBasedExcelExtractor)</action>
            <action dev="POI-DEVELOPERS" type="add">ExtractorFactory can now be told to prefer Event Based extractors (current Excel only) on a per-thread or overall basis</action>
            <action dev="POI-DEVELOPERS" type="fix">48544 - avoid failures in XLSX2CSV when shared string table is missing</action>
index 5e21bdf58e0b808bffec856c235d92744413cef0..60c11d35210a1566721c22c4a4e185e2bd35e69f 100644 (file)
 ==================================================================== */
 package org.apache.poi.hssf.eventusermodel;
 
+import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 import org.apache.poi.hssf.record.CellValueRecordInterface;
@@ -37,12 +39,28 @@ import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
  */
 public class FormatTrackingHSSFListener implements HSSFListener {
        private final HSSFListener _childListener;
-       private HSSFDataFormatter _formatter = new HSSFDataFormatter();
+       private final HSSFDataFormatter _formatter;
+       private final NumberFormat _defaultFormat;
        private final Map<Integer, FormatRecord> _customFormatRecords = new Hashtable<Integer, FormatRecord>();
        private final List<ExtendedFormatRecord> _xfRecords = new ArrayList<ExtendedFormatRecord>();
 
+       /**
+        * Creates a format tracking wrapper around the given listener, using
+        * the {@link Locale#getDefault() default locale} for the formats.
+        */
        public FormatTrackingHSSFListener(HSSFListener childListener) {
+               this(childListener, Locale.getDefault());
+       }
+
+       /**
+        * Creates a format tracking wrapper around the given listener, using
+        * the given locale for the formats.
+        */
+       public FormatTrackingHSSFListener(
+                       HSSFListener childListener, Locale locale) {
                _childListener = childListener;
+               _formatter = new HSSFDataFormatter(locale);
+               _defaultFormat = NumberFormat.getInstance(locale);
        }
 
        protected int getNumberOfCustomFormats() {
@@ -104,7 +122,7 @@ public class FormatTrackingHSSFListener implements HSSFListener {
                String formatString = getFormatString(cell);
 
                if (formatString == null) {
-                       return Double.toString(value);
+                       return _defaultFormat.format(value);
                }
                // Format, using the nice new
                // HSSFDataFormatter to do the work for us
index 6396492d8e9d60ce703a716b26bc7237c5fb6acf..0024639ff54e839ea322dbd06d36b7be6716d3c3 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.usermodel;
 import java.text.DecimalFormat;
 import java.text.Format;
 import java.text.SimpleDateFormat;
+import java.util.Locale;
 
 import org.apache.poi.ss.usermodel.DataFormatter;
 
@@ -66,4 +67,18 @@ import org.apache.poi.ss.usermodel.DataFormatter;
  */
 public final class HSSFDataFormatter extends DataFormatter {
 
+    /**
+     * Creates a formatter using the given locale.
+     */
+    public HSSFDataFormatter(Locale locale) {
+        super(locale);
+    }
+
+    /**
+     * Creates a formatter using the {@link Locale#getDefault() default locale}.
+     */
+    public HSSFDataFormatter() {
+        this(Locale.getDefault());
+    }
+
 }
index bb7ef000e4149e04f677e888c15bc78687e7bd04..053e37cb504e7e574a6f217ae057cc1a8d731914 100644 (file)
@@ -77,11 +77,21 @@ public class DataFormatter {
     /** A regex to find patterns like [$$-1009] and [$?-452]. */
     private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
 
+    /**
+     * The decimal symbols of the locale used for formatting values.
+     */
+    private final DecimalFormatSymbols decimalSymbols;
+
+    /**
+     * The date symbols of the locale used for formatting values.
+     */
+    private final DateFormatSymbols dateSymbols;
+
     /** <em>General</em> format for whole numbers. */
-    private static final Format generalWholeNumFormat = new DecimalFormat("#");
+    private final Format generalWholeNumFormat;
 
     /** <em>General</em> format for decimal numbers. */
-    private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########");
+    private final Format generalDecimalNumFormat;
 
     /** A default format to use when a number pattern cannot be parsed. */
     private Format defaultNumFormat;
@@ -90,13 +100,25 @@ public class DataFormatter {
      * A map to cache formats.
      *  Map<String,Format> formats
      */
-    private final Map formats;
+    private final Map<String,Format> formats;
 
     /**
-     * Constructor
+     * Creates a formatter using the {@link Locale#getDefault() default locale}.
      */
     public DataFormatter() {
-        formats = new HashMap();
+        this(Locale.getDefault());
+    }
+
+    /**
+     * Creates a formatter using the given locale.
+     */
+    public DataFormatter(Locale locale) {
+        dateSymbols = new DateFormatSymbols(locale);
+        decimalSymbols = new DecimalFormatSymbols(locale);
+        generalWholeNumFormat = new DecimalFormat("#", decimalSymbols);
+        generalDecimalNumFormat = new DecimalFormat("#.##########", decimalSymbols);
+
+        formats = new HashMap<String,Format>();
 
         // init built-in formats
 
@@ -143,7 +165,7 @@ public class DataFormatter {
     }
 
     private Format getFormat(double cellValue, int formatIndex, String formatStr) {
-        Format format = (Format)formats.get(formatStr);
+        Format format = formats.get(formatStr);
         if (format != null) {
             return format;
         }
@@ -242,7 +264,7 @@ public class DataFormatter {
         StringBuffer sb = new StringBuffer();
         char[] chars = formatStr.toCharArray();
         boolean mIsMonth = true;
-        List ms = new ArrayList();
+        List<Integer> ms = new ArrayList<Integer>();
         for(int j=0; j<chars.length; j++) {
             char c = chars[j];
             if (c == 'h' || c == 'H') {
@@ -267,7 +289,7 @@ public class DataFormatter {
                 sb.append('s');
                 // if 'M' precedes 's' it should be minutes ('m')
                 for (int i = 0; i < ms.size(); i++) {
-                    int index = ((Integer)ms.get(i)).intValue();
+                    int index = ms.get(i).intValue();
                     if (sb.charAt(index) == 'M') {
                         sb.replace(index, index+1, "m");
                     }
@@ -295,7 +317,7 @@ public class DataFormatter {
         formatStr = sb.toString();
 
         try {
-            return new SimpleDateFormat(formatStr);
+            return new SimpleDateFormat(formatStr, dateSymbols);
         } catch(IllegalArgumentException iae) {
 
             // the pattern could not be parsed correctly,
@@ -335,7 +357,7 @@ public class DataFormatter {
         }
 
         try {
-            return new DecimalFormat(sb.toString());
+            return new DecimalFormat(sb.toString(), decimalSymbols);
         } catch(IllegalArgumentException iae) {
 
             // the pattern could not be parsed correctly,
@@ -520,9 +542,9 @@ public class DataFormatter {
      * @see java.text.Format#format
      */
     public void setDefaultNumberFormat(Format format) {
-        Iterator itr = formats.entrySet().iterator();
+        Iterator<Map.Entry<String,Format>> itr = formats.entrySet().iterator();
         while(itr.hasNext()) {
-            Map.Entry entry = (Map.Entry)itr.next();
+            Map.Entry<String,Format> entry = itr.next();
             if (entry.getValue() == generalDecimalNumFormat
                     || entry.getValue() == generalWholeNumFormat) {
                 entry.setValue(format);
@@ -562,7 +584,8 @@ public class DataFormatter {
      *
      * @author James May
      */
-    private static final class SSNFormat extends Format {
+    @SuppressWarnings("serial")
+   private static final class SSNFormat extends Format {
         public static final Format instance = new SSNFormat();
         private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
         private SSNFormat() {
@@ -593,7 +616,8 @@ public class DataFormatter {
      * built-in formatting for Zip + 4.
      * @author James May
      */
-    private static final class ZipPlusFourFormat extends Format {
+    @SuppressWarnings("serial")
+   private static final class ZipPlusFourFormat extends Format {
         public static final Format instance = new ZipPlusFourFormat();
         private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
         private ZipPlusFourFormat() {
@@ -623,7 +647,8 @@ public class DataFormatter {
      * built-in phone number formatting.
      * @author James May
      */
-    private static final class PhoneFormat extends Format {
+    @SuppressWarnings("serial")
+   private static final class PhoneFormat extends Format {
         public static final Format instance = new PhoneFormat();
         private static final DecimalFormat df = createIntegerOnlyFormat("##########");
         private PhoneFormat() {
diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java
new file mode 100644 (file)
index 0000000..73c15e8
--- /dev/null
@@ -0,0 +1,43 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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
+
+       http://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 org.apache.poi.ss.usermodel;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests of {@link DataFormatter}
+ *
+ */
+public class TestDataFormatter extends TestCase {
+    /**
+     * Test that we use the specified locale when deciding
+     *   how to format normal numbers
+     */
+    public void testLocale() {
+       DataFormatter dfUS = new DataFormatter(Locale.US);
+       DataFormatter dfFR = new DataFormatter(Locale.FRENCH);
+       
+       assertEquals("1234", dfUS.formatRawCellContents(1234, -1, "@"));
+       assertEquals("1234", dfFR.formatRawCellContents(1234, -1, "@"));
+       
+       assertEquals("12.34", dfUS.formatRawCellContents(12.34, -1, "@"));
+       assertEquals("12,34", dfFR.formatRawCellContents(12.34, -1, "@"));
+    }
+}