Mention about Locale definitions in Excel cell data format strings

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1710459 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2015-10-25 16:13:16 +00:00
parent 74f6f424ad
commit dc947416d4
4 changed files with 60 additions and 4 deletions

View File

@ -33,6 +33,7 @@ import org.apache.poi.ss.usermodel.ConditionalFormatting;
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil; 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 * 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 * fourth part (example: text in the cell's usual color, with the text value
* surround by brackets). </dl> * surround by brackets). </dl>
* <p/> * <p/>
* A given format part may specify a given Locale, by including something
* like <tt>[$$-409]</tt> or <tt>[$\u00A3-809]</tt> or <tt>[$-40C]</tt>. These
* are (currently) largely ignored. You can use {@link DateFormatConverter}
* to look these up into Java Locales if desired.
* <p/>
* In addition to these, there is a general format that is used when no format * 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} * is specified. This formatting is presented by the {@link #GENERAL_FORMAT}
* object. * object.

View File

@ -42,6 +42,7 @@ import java.util.regex.Pattern;
import org.apache.poi.ss.format.CellFormat; import org.apache.poi.ss.format.CellFormat;
import org.apache.poi.ss.format.CellFormatResult; 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.ss.util.NumberToTextConverter;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
@ -105,6 +106,15 @@ import org.apache.poi.util.POILogger;
* <li>simulate Excel's handling of a format string of all # when the value is 0. * <li>simulate Excel's handling of a format string of all # when the value is 0.
* Excel will output "", <code>DataFormatter</code> will output "0". * Excel will output "", <code>DataFormatter</code> will output "0".
* </ul> * </ul>
* <p>
* 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
* <code>[$-809]d/m/yy h:mm AM/PM</code> 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 { public class DataFormatter implements Observer {
private static final String defaultFractionWholePartFormat = "#"; private static final String defaultFractionWholePartFormat = "#";
@ -1129,13 +1139,17 @@ public class DataFormatter implements Observer {
* Constant, non-cachable wrapper around a {@link CellFormatResult} * Constant, non-cachable wrapper around a {@link CellFormatResult}
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
private static final class CellFormatResultWrapper extends Format { private final class CellFormatResultWrapper extends Format {
private final CellFormatResult result; private final CellFormatResult result;
private CellFormatResultWrapper(CellFormatResult result) { private CellFormatResultWrapper(CellFormatResult result) {
this.result = result; this.result = result;
} }
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { 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) { public Object parseObject(String source, ParsePosition pos) {
return null; // Not supported return null; // Not supported

View File

@ -42,10 +42,9 @@ import org.apache.poi.util.POILogger;
* cellStyle.setDataFormat(poiFormat.getFormat(excelFormatPattern)); * cellStyle.setDataFormat(poiFormat.getFormat(excelFormatPattern));
* cell.setCellValue(new Date()); * cell.setCellValue(new Date());
* cell.setCellStyle(cellStyle); // formats date as '2012\u5e743\u670817\u65e5' * cell.setCellStyle(cellStyle); // formats date as '2012\u5e743\u670817\u65e5'
*
* </code></pre> * </code></pre>
* *
* * TODO Generalise this for all Excel format strings
*/ */
public class DateFormatConverter { public class DateFormatConverter {
private static POILogger logger = POILogFactory.getLogger(DateFormatConverter.class); private static POILogger logger = POILogFactory.getLogger(DateFormatConverter.class);

View File

@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
public class TestCellFormat { public class TestCellFormat {
@ -923,4 +924,40 @@ public class TestCellFormat {
wb.close(); 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
}
} }