diff --git a/src/java/org/apache/poi/ss/format/CellFormat.java b/src/java/org/apache/poi/ss/format/CellFormat.java index fadfe2324b..e5333d6018 100644 --- a/src/java/org/apache/poi/ss/format/CellFormat.java +++ b/src/java/org/apache/poi/ss/format/CellFormat.java @@ -33,6 +33,7 @@ import org.apache.poi.ss.usermodel.ConditionalFormatting; 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; /** * Format a value according to the standard Excel behavior. This "standard" is @@ -64,6 +65,11 @@ import org.apache.poi.ss.usermodel.DateUtil; * fourth part (example: text in the cell's usual color, with the text value * surround by brackets). *

+ * A given format part may specify a given Locale, by including something + * like [$$-409] or [$\u00A3-809] or [$-40C]. These + * are (currently) largely ignored. You can use {@link DateFormatConverter} + * to look these up into Java Locales if desired. + *

* In addition to these, there is a general format that is used when no format * is specified. This formatting is presented by the {@link #GENERAL_FORMAT} * object. diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index add3be8cef..a6a53d04f6 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -42,6 +42,7 @@ import java.util.regex.Pattern; import org.apache.poi.ss.format.CellFormat; import org.apache.poi.ss.format.CellFormatResult; +import org.apache.poi.ss.util.DateFormatConverter; import org.apache.poi.ss.util.NumberToTextConverter; import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; @@ -105,6 +106,15 @@ import org.apache.poi.util.POILogger; *

  • simulate Excel's handling of a format string of all # when the value is 0. * Excel will output "", DataFormatter will output "0". * + *

    + * Some formats are automatically "localised" by Excel, eg show as mm/dd/yyyy when + * loaded in Excel in some Locales but as dd/mm/yyyy in others. These are always + * returned in the "default" (US) format, as stored in the file. + * Some format strings request an alternate locale, eg + * [$-809]d/m/yy h:mm AM/PM which explicitly requests UK locale. + * These locale directives are (currently) ignored. + * You can use {@link DateFormatConverter} to do some of this localisation if + * you need it. */ public class DataFormatter implements Observer { private static final String defaultFractionWholePartFormat = "#"; @@ -1129,13 +1139,17 @@ public class DataFormatter implements Observer { * Constant, non-cachable wrapper around a {@link CellFormatResult} */ @SuppressWarnings("serial") - private static final class CellFormatResultWrapper extends Format { + private final class CellFormatResultWrapper extends Format { private final CellFormatResult result; private CellFormatResultWrapper(CellFormatResult result) { this.result = result; } public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(result.text); + if (emulateCsv) { + return toAppendTo.append(result.text); + } else { + return toAppendTo.append(result.text.trim()); + } } public Object parseObject(String source, ParsePosition pos) { return null; // Not supported diff --git a/src/java/org/apache/poi/ss/util/DateFormatConverter.java b/src/java/org/apache/poi/ss/util/DateFormatConverter.java index aa343f3722..6339a6ea7a 100644 --- a/src/java/org/apache/poi/ss/util/DateFormatConverter.java +++ b/src/java/org/apache/poi/ss/util/DateFormatConverter.java @@ -42,10 +42,9 @@ import org.apache.poi.util.POILogger; * cellStyle.setDataFormat(poiFormat.getFormat(excelFormatPattern)); * cell.setCellValue(new Date()); * cell.setCellStyle(cellStyle); // formats date as '2012\u5e743\u670817\u65e5' - * * * - * + * TODO Generalise this for all Excel format strings */ public class DateFormatConverter { private static POILogger logger = POILogFactory.getLogger(DateFormatConverter.class); diff --git a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java index b7983a3c80..13a1f4b2e3 100644 --- a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java +++ b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java @@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.LocaleUtil; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; public class TestCellFormat { @@ -923,4 +924,40 @@ public class TestCellFormat { wb.close(); } } + + @Test + @Ignore("TODO") // TODO + public void testAccountingFormats() throws IOException { + char pound = '\u00A3'; + char euro = '\u20AC'; + + // Accounting -> 0 decimal places, default currency symbol + String formatDft = "_-\"$\"* #,##0_-;\\-\"$\"* #,##0_-;_-\"$\"* \"-\"_-;_-@_-"; + // Accounting -> 0 decimal places, US currency symbol + String formatUS = "_-[$$-409]* #,##0_ ;_-[$$-409]* -#,##0 ;_-[$$-409]* \"-\"_ ;_-@_ "; + // Accounting -> 0 decimal places, UK currency symbol + String formatUK = "_-[$"+pound+"-809]* #,##0_-;\\-[$"+pound+"-809]* #,##0_-;_-[$"+pound+"-809]* \"-\"??_-;_-@_-"; + // Accounting -> 0 decimal places, French currency symbol + String formatFR = "_-[$"+euro+"-40C]* #,##0_-;\\-[$"+euro+"-40C]* #,##0_-;_-[$"+euro+"-40C]* \"-\"??_-;_-@_-"; + + // Has +ve, -ve and zero rules + CellFormat cfDft = CellFormat.getInstance(formatDft); + CellFormat cfUS = CellFormat.getInstance(formatUS); + CellFormat cfUK = CellFormat.getInstance(formatUK); + CellFormat cfFR = CellFormat.getInstance(formatFR); + + // For +ve numbers, should be Space + currency symbol + spaces + whole number with commas + space + assertEquals(" $ 12 ",cfDft.apply(Double.valueOf(12.33)).text); + assertEquals(" $ 12 ", cfUS.apply(Double.valueOf(12.33)).text); + assertEquals(" "+pound+" 12 ", cfUK.apply(Double.valueOf(12.33)).text); + assertEquals(" "+pound+" 12 ", cfFR.apply(Double.valueOf(12.33)).text); + assertEquals(" "+pound+" 16,789 ", cfUK.apply(Double.valueOf(16789.2)).text); + // TODO More + + // For -ve numbers, should be Minus + currency symbol + spaces + whole number with commas + // TODO + + // For zero, should be Space + currency symbol + spaces + Minus + spaces + // TODO + } } \ No newline at end of file