==================================================================== */
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;
*/
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() {
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
/** 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;
* 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
}
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;
}
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') {
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");
}
formatStr = sb.toString();
try {
- return new SimpleDateFormat(formatStr);
+ return new SimpleDateFormat(formatStr, dateSymbols);
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
}
try {
- return new DecimalFormat(sb.toString());
+ return new DecimalFormat(sb.toString(), decimalSymbols);
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
* @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);
*
* @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() {
* 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() {
* 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() {
--- /dev/null
+/* ====================================================================
+ 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, "@"));
+ }
+}