More tweaks for bug 45404. Fixes for JDK 1.4, improved member scoping and formatting.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@680470 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3fbf71f9d9
commit
bc0461c5ed
@ -73,69 +73,55 @@ import java.util.regex.Pattern;
|
|||||||
* @author James May (james dot may at fmr dot com)
|
* @author James May (james dot may at fmr dot com)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HSSFDataFormatter {
|
public final class HSSFDataFormatter {
|
||||||
|
|
||||||
/** Pattern to find a number format: "0" or "#" */
|
/** Pattern to find a number format: "0" or "#" */
|
||||||
protected Pattern numPattern;
|
private static final Pattern numPattern = Pattern.compile("[0#]+");
|
||||||
|
|
||||||
/** Pattern to find days of week as text "ddd...." */
|
/** Pattern to find days of week as text "ddd...." */
|
||||||
protected Pattern daysAsText;
|
private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
/** Pattern to find "AM/PM" marker */
|
/** Pattern to find "AM/PM" marker */
|
||||||
protected Pattern amPmPattern;
|
private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
/** A regex to find patterns like [$$-1009] and [$<24>-452]. */
|
/** A regex to find patterns like [$$-1009] and [$<24>-452]. */
|
||||||
protected Pattern specialPatternGroup;
|
private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
|
||||||
|
|
||||||
/** <em>General</em> format for whole numbers. */
|
/** <em>General</em> format for whole numbers. */
|
||||||
protected Format generalWholeNumFormat;
|
private static final Format generalWholeNumFormat = new DecimalFormat("#");
|
||||||
|
|
||||||
/** <em>General</em> format for decimal numbers. */
|
/** <em>General</em> format for decimal numbers. */
|
||||||
protected Format generalDecimalNumFormat;
|
private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########");
|
||||||
|
|
||||||
/** A default format to use when a number pattern cannot be parsed. */
|
/** A default format to use when a number pattern cannot be parsed. */
|
||||||
protected Format defaultNumFormat;
|
private Format defaultNumFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map to cache formats.
|
* A map to cache formats.
|
||||||
* Map<String,Format> formats
|
* Map<String,Format> formats
|
||||||
*/
|
*/
|
||||||
protected Map formats;
|
private final Map formats;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public HSSFDataFormatter() {
|
public HSSFDataFormatter() {
|
||||||
numPattern = Pattern.compile("[0#]+");
|
|
||||||
daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
|
|
||||||
amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
|
|
||||||
specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
|
|
||||||
generalWholeNumFormat = new DecimalFormat("#");
|
|
||||||
generalDecimalNumFormat = new DecimalFormat("#.##########");
|
|
||||||
formats = new HashMap();
|
formats = new HashMap();
|
||||||
|
|
||||||
// init built-in formats
|
// init built-in formats
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Format zipFormat = ZipPlusFourFormat.instance;
|
||||||
* Initialize the formatter. Called after construction.
|
|
||||||
*/
|
|
||||||
protected void init() {
|
|
||||||
|
|
||||||
ZipPlusFourFormat zipFormat = new ZipPlusFourFormat();
|
|
||||||
addFormat("00000\\-0000", zipFormat);
|
addFormat("00000\\-0000", zipFormat);
|
||||||
addFormat("00000-0000", zipFormat);
|
addFormat("00000-0000", zipFormat);
|
||||||
|
|
||||||
PhoneFormat phoneFormat = new PhoneFormat();
|
Format phoneFormat = PhoneFormat.instance;
|
||||||
// allow for format string variations
|
// allow for format string variations
|
||||||
addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
|
addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
|
||||||
addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat);
|
addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat);
|
||||||
addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
|
addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
|
||||||
addFormat("###-####;(###) ###-####", phoneFormat);
|
addFormat("###-####;(###) ###-####", phoneFormat);
|
||||||
|
|
||||||
SSNFormat ssnFormat = new SSNFormat();
|
Format ssnFormat = SSNFormat.instance;
|
||||||
addFormat("000\\-00\\-0000", ssnFormat);
|
addFormat("000\\-00\\-0000", ssnFormat);
|
||||||
addFormat("000-00-0000", ssnFormat);
|
addFormat("000-00-0000", ssnFormat);
|
||||||
}
|
}
|
||||||
@ -153,7 +139,7 @@ public class HSSFDataFormatter {
|
|||||||
* @param cell The cell to retrieve a Format for
|
* @param cell The cell to retrieve a Format for
|
||||||
* @return A Format for the format String
|
* @return A Format for the format String
|
||||||
*/
|
*/
|
||||||
protected Format getFormat(HSSFCell cell) {
|
private Format getFormat(HSSFCell cell) {
|
||||||
if ( cell.getCellStyle() == null) {
|
if ( cell.getCellStyle() == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -170,18 +156,17 @@ public class HSSFDataFormatter {
|
|||||||
Format format = (Format)formats.get(formatStr);
|
Format format = (Format)formats.get(formatStr);
|
||||||
if (format != null) {
|
if (format != null) {
|
||||||
return format;
|
return format;
|
||||||
} else if (formatStr.equals("General")) {
|
}
|
||||||
|
if (formatStr.equals("General")) {
|
||||||
if (HSSFDataFormatter.isWholeNumber(cellValue)) {
|
if (HSSFDataFormatter.isWholeNumber(cellValue)) {
|
||||||
return generalWholeNumFormat;
|
return generalWholeNumFormat;
|
||||||
} else {
|
}
|
||||||
return generalDecimalNumFormat;
|
return generalDecimalNumFormat;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
format = createFormat(cellValue, formatIndex, formatStr);
|
format = createFormat(cellValue, formatIndex, formatStr);
|
||||||
formats.put(formatStr, format);
|
formats.put(formatStr, format);
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return a Format based on the format string from a cell's
|
* Create and return a Format based on the format string from a cell's
|
||||||
@ -190,8 +175,7 @@ public class HSSFDataFormatter {
|
|||||||
* @param cell The Excel cell
|
* @param cell The Excel cell
|
||||||
* @return A Format representing the excel format. May return null.
|
* @return A Format representing the excel format. May return null.
|
||||||
*/
|
*/
|
||||||
protected Format createFormat(HSSFCell cell) {
|
public Format createFormat(HSSFCell cell) {
|
||||||
String sFormat = cell.getCellStyle().getDataFormatString();
|
|
||||||
|
|
||||||
int formatIndex = cell.getCellStyle().getDataFormat();
|
int formatIndex = cell.getCellStyle().getDataFormat();
|
||||||
String formatStr = cell.getCellStyle().getDataFormatString();
|
String formatStr = cell.getCellStyle().getDataFormatString();
|
||||||
@ -202,12 +186,9 @@ public class HSSFDataFormatter {
|
|||||||
// remove color formatting if present
|
// remove color formatting if present
|
||||||
String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", "");
|
String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", "");
|
||||||
|
|
||||||
// Try to extract special characters like currency
|
// try to extract special characters like currency
|
||||||
// Need to re-create the matcher each time, as the string
|
Matcher m = specialPatternGroup.matcher(formatStr);
|
||||||
// will potentially change on each pass
|
while(m.find()) {
|
||||||
Matcher m;
|
|
||||||
try {
|
|
||||||
while((m = specialPatternGroup.matcher(formatStr)).find()) {
|
|
||||||
String match = m.group();
|
String match = m.group();
|
||||||
String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
|
String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
|
||||||
if (symbol.indexOf('$') > -1) {
|
if (symbol.indexOf('$') > -1) {
|
||||||
@ -218,20 +199,27 @@ public class HSSFDataFormatter {
|
|||||||
symbol = sb.toString();
|
symbol = sb.toString();
|
||||||
}
|
}
|
||||||
formatStr = m.replaceAll(symbol);
|
formatStr = m.replaceAll(symbol);
|
||||||
}
|
m = specialPatternGroup.matcher(formatStr);
|
||||||
} catch (Exception e) {
|
|
||||||
return getDefaultFormat(cellValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(formatStr == null || formatStr.trim().length() == 0) {
|
if(formatStr == null || formatStr.trim().length() == 0) {
|
||||||
return getDefaultFormat(cellValue);
|
return getDefaultFormat(cellValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Format returnVal = null;
|
|
||||||
StringBuffer sb = null;
|
|
||||||
|
|
||||||
if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
|
if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
|
||||||
HSSFDateUtil.isValidExcelDate(cellValue)) {
|
HSSFDateUtil.isValidExcelDate(cellValue)) {
|
||||||
|
return createDateFormat(formatStr, cellValue);
|
||||||
|
}
|
||||||
|
if (numPattern.matcher(formatStr).find()) {
|
||||||
|
return createNumberFormat(formatStr, cellValue);
|
||||||
|
}
|
||||||
|
// TODO - when does this occur?
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Format createDateFormat(String pFormatStr, double cellValue) {
|
||||||
|
String formatStr = pFormatStr;
|
||||||
formatStr = formatStr.replaceAll("\\\\-","-");
|
formatStr = formatStr.replaceAll("\\\\-","-");
|
||||||
formatStr = formatStr.replaceAll("\\\\,",",");
|
formatStr = formatStr.replaceAll("\\\\,",",");
|
||||||
formatStr = formatStr.replaceAll("\\\\ "," ");
|
formatStr = formatStr.replaceAll("\\\\ "," ");
|
||||||
@ -239,9 +227,12 @@ public class HSSFDataFormatter {
|
|||||||
boolean hasAmPm = false;
|
boolean hasAmPm = false;
|
||||||
Matcher amPmMatcher = amPmPattern.matcher(formatStr);
|
Matcher amPmMatcher = amPmPattern.matcher(formatStr);
|
||||||
while (amPmMatcher.find()) {
|
while (amPmMatcher.find()) {
|
||||||
formatStr = amPmMatcher.replaceAll("a");
|
formatStr = amPmMatcher.replaceAll("@");
|
||||||
hasAmPm = true;
|
hasAmPm = true;
|
||||||
|
amPmMatcher = amPmPattern.matcher(formatStr);
|
||||||
}
|
}
|
||||||
|
formatStr = formatStr.replaceAll("@", "a");
|
||||||
|
|
||||||
|
|
||||||
Matcher dateMatcher = daysAsText.matcher(formatStr);
|
Matcher dateMatcher = daysAsText.matcher(formatStr);
|
||||||
if (dateMatcher.find()) {
|
if (dateMatcher.find()) {
|
||||||
@ -258,7 +249,7 @@ public class HSSFDataFormatter {
|
|||||||
Excel displays the month instead of minutes."
|
Excel displays the month instead of minutes."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
char[] chars = formatStr.toCharArray();
|
char[] chars = formatStr.toCharArray();
|
||||||
boolean mIsMonth = true;
|
boolean mIsMonth = true;
|
||||||
List ms = new ArrayList();
|
List ms = new ArrayList();
|
||||||
@ -314,7 +305,7 @@ public class HSSFDataFormatter {
|
|||||||
formatStr = sb.toString();
|
formatStr = sb.toString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
returnVal = new SimpleDateFormat(formatStr);
|
return new SimpleDateFormat(formatStr);
|
||||||
} catch(IllegalArgumentException iae) {
|
} catch(IllegalArgumentException iae) {
|
||||||
|
|
||||||
// the pattern could not be parsed correctly,
|
// the pattern could not be parsed correctly,
|
||||||
@ -322,8 +313,10 @@ public class HSSFDataFormatter {
|
|||||||
return getDefaultFormat(cellValue);
|
return getDefaultFormat(cellValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (numPattern.matcher(formatStr).find()) {
|
}
|
||||||
sb = new StringBuffer(formatStr);
|
|
||||||
|
private Format createNumberFormat(String formatStr, double cellValue) {
|
||||||
|
StringBuffer sb = new StringBuffer(formatStr);
|
||||||
for (int i = 0; i < sb.length(); i++) {
|
for (int i = 0; i < sb.length(); i++) {
|
||||||
char c = sb.charAt(i);
|
char c = sb.charAt(i);
|
||||||
//handle (#,##0_);
|
//handle (#,##0_);
|
||||||
@ -350,9 +343,9 @@ public class HSSFDataFormatter {
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formatStr = sb.toString();
|
|
||||||
try {
|
try {
|
||||||
returnVal = new DecimalFormat(formatStr);
|
return new DecimalFormat(sb.toString());
|
||||||
} catch(IllegalArgumentException iae) {
|
} catch(IllegalArgumentException iae) {
|
||||||
|
|
||||||
// the pattern could not be parsed correctly,
|
// the pattern could not be parsed correctly,
|
||||||
@ -360,13 +353,11 @@ public class HSSFDataFormatter {
|
|||||||
return getDefaultFormat(cellValue);
|
return getDefaultFormat(cellValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the double value represents a whole number
|
* Return true if the double value represents a whole number
|
||||||
* @param d the double value to check
|
* @param d the double value to check
|
||||||
* @return true if d is a whole number
|
* @return <code>true</code> if d is a whole number
|
||||||
*/
|
*/
|
||||||
private static boolean isWholeNumber(double d) {
|
private static boolean isWholeNumber(double d) {
|
||||||
return d == Math.floor(d);
|
return d == Math.floor(d);
|
||||||
@ -377,7 +368,7 @@ public class HSSFDataFormatter {
|
|||||||
* @param cell The cell
|
* @param cell The cell
|
||||||
* @return a default format
|
* @return a default format
|
||||||
*/
|
*/
|
||||||
protected Format getDefaultFormat(HSSFCell cell) {
|
public Format getDefaultFormat(HSSFCell cell) {
|
||||||
return getDefaultFormat(cell.getNumericCellValue());
|
return getDefaultFormat(cell.getNumericCellValue());
|
||||||
}
|
}
|
||||||
private Format getDefaultFormat(double cellValue) {
|
private Format getDefaultFormat(double cellValue) {
|
||||||
@ -386,11 +377,11 @@ public class HSSFDataFormatter {
|
|||||||
return defaultNumFormat;
|
return defaultNumFormat;
|
||||||
|
|
||||||
// otherwise use general format
|
// otherwise use general format
|
||||||
} else if (isWholeNumber(cellValue)){
|
|
||||||
return generalWholeNumFormat;
|
|
||||||
} else {
|
|
||||||
return generalDecimalNumFormat;
|
|
||||||
}
|
}
|
||||||
|
if (isWholeNumber(cellValue)){
|
||||||
|
return generalWholeNumFormat;
|
||||||
|
}
|
||||||
|
return generalDecimalNumFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -401,14 +392,13 @@ public class HSSFDataFormatter {
|
|||||||
* @param cell The cell
|
* @param cell The cell
|
||||||
* @return a formatted date string
|
* @return a formatted date string
|
||||||
*/
|
*/
|
||||||
protected String getFormattedDateString(HSSFCell cell) {
|
private String getFormattedDateString(HSSFCell cell) {
|
||||||
Format dateFormat = getFormat(cell);
|
Format dateFormat = getFormat(cell);
|
||||||
Date d = cell.getDateCellValue();
|
Date d = cell.getDateCellValue();
|
||||||
if (dateFormat != null) {
|
if (dateFormat != null) {
|
||||||
return dateFormat.format(d);
|
return dateFormat.format(d);
|
||||||
} else {
|
|
||||||
return d.toString();
|
|
||||||
}
|
}
|
||||||
|
return d.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -420,15 +410,14 @@ public class HSSFDataFormatter {
|
|||||||
* @param cell The cell
|
* @param cell The cell
|
||||||
* @return a formatted number string
|
* @return a formatted number string
|
||||||
*/
|
*/
|
||||||
protected String getFormattedNumberString(HSSFCell cell) {
|
private String getFormattedNumberString(HSSFCell cell) {
|
||||||
|
|
||||||
Format numberFormat = getFormat(cell);
|
Format numberFormat = getFormat(cell);
|
||||||
double d = cell.getNumericCellValue();
|
double d = cell.getNumericCellValue();
|
||||||
if (numberFormat != null) {
|
if (numberFormat == null) {
|
||||||
return numberFormat.format(new Double(d));
|
|
||||||
} else {
|
|
||||||
return String.valueOf(d);
|
return String.valueOf(d);
|
||||||
}
|
}
|
||||||
|
return numberFormat.format(new Double(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -443,20 +432,17 @@ public class HSSFDataFormatter {
|
|||||||
|
|
||||||
Format dateFormat = getFormat(value, formatIndex, formatString);
|
Format dateFormat = getFormat(value, formatIndex, formatString);
|
||||||
Date d = HSSFDateUtil.getJavaDate(value);
|
Date d = HSSFDateUtil.getJavaDate(value);
|
||||||
if (dateFormat != null) {
|
if (dateFormat == null) {
|
||||||
return dateFormat.format(d);
|
|
||||||
} else {
|
|
||||||
return d.toString();
|
return d.toString();
|
||||||
}
|
}
|
||||||
} else {
|
return dateFormat.format(d);
|
||||||
// Number
|
}
|
||||||
|
// else Number
|
||||||
Format numberFormat = getFormat(value, formatIndex, formatString);
|
Format numberFormat = getFormat(value, formatIndex, formatString);
|
||||||
if (numberFormat != null) {
|
if (numberFormat == null) {
|
||||||
return numberFormat.format(new Double(value));
|
|
||||||
} else {
|
|
||||||
return String.valueOf(value);
|
return String.valueOf(value);
|
||||||
}
|
}
|
||||||
}
|
return numberFormat.format(new Double(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -486,58 +472,51 @@ public class HSSFDataFormatter {
|
|||||||
* String (""). Formula cells will be evaluated using the given
|
* String (""). Formula cells will be evaluated using the given
|
||||||
* {@link HSSFFormulaEvaluator} if the evaluator is non-null. If the
|
* {@link HSSFFormulaEvaluator} if the evaluator is non-null. If the
|
||||||
* evaluator is null, then the formula String will be returned. The caller
|
* evaluator is null, then the formula String will be returned. The caller
|
||||||
* is responsible for setting the currentRow on the evaluator, otherwise an
|
* is responsible for setting the currentRow on the evaluator
|
||||||
* IllegalArgumentException may be thrown.
|
|
||||||
*</p>
|
*</p>
|
||||||
*
|
*
|
||||||
* @param cell The cell
|
* @param cell The cell (can be null)
|
||||||
* @param evaluator The HSSFFormulaEvaluator (can be null)
|
* @param evaluator The HSSFFormulaEvaluator (can be null)
|
||||||
* @return a string value of the cell
|
* @return a string value of the cell
|
||||||
* @throws IllegalArgumentException if cell type is <code>
|
|
||||||
* HSSFCell.CELL_TYPE_FORMULA</code> <b>and</b> evaluator is not null
|
|
||||||
* <b>and</b> the evlaluator's currentRow has not been set.
|
|
||||||
*/
|
*/
|
||||||
public String formatCellValue(HSSFCell cell,
|
public String formatCellValue(HSSFCell cell,
|
||||||
HSSFFormulaEvaluator evaluator) throws IllegalArgumentException {
|
HSSFFormulaEvaluator evaluator) throws IllegalArgumentException {
|
||||||
|
|
||||||
String value = "";
|
|
||||||
if (cell == null) {
|
if (cell == null) {
|
||||||
return value;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellType = cell.getCellType();
|
int cellType = cell.getCellType();
|
||||||
if (evaluator != null && cellType == HSSFCell.CELL_TYPE_FORMULA) {
|
if (evaluator != null && cellType == HSSFCell.CELL_TYPE_FORMULA) {
|
||||||
try {
|
try {
|
||||||
cellType = evaluator.evaluateFormulaCell(cell);
|
cellType = evaluator.evaluateFormulaCell(cell);
|
||||||
} catch (Throwable t) {
|
} catch (RuntimeException e) {
|
||||||
throw new IllegalArgumentException("Did you forget to set the current" +
|
throw new RuntimeException("Did you forget to set the current" +
|
||||||
" row on the HSSFFormulaEvaluator?", t);
|
" row on the HSSFFormulaEvaluator?", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (cellType)
|
switch (cellType)
|
||||||
{
|
{
|
||||||
case HSSFCell.CELL_TYPE_FORMULA :
|
case HSSFCell.CELL_TYPE_FORMULA :
|
||||||
// should only occur if evaluator is null
|
// should only occur if evaluator is null
|
||||||
value = cell.getCellFormula();
|
return cell.getCellFormula();
|
||||||
break;
|
|
||||||
|
|
||||||
case HSSFCell.CELL_TYPE_NUMERIC :
|
case HSSFCell.CELL_TYPE_NUMERIC :
|
||||||
|
|
||||||
if (HSSFDateUtil.isCellDateFormatted(cell)) {
|
if (HSSFDateUtil.isCellDateFormatted(cell)) {
|
||||||
value = getFormattedDateString(cell);
|
return getFormattedDateString(cell);
|
||||||
} else {
|
|
||||||
value = getFormattedNumberString(cell);
|
|
||||||
}
|
}
|
||||||
break;
|
return getFormattedNumberString(cell);
|
||||||
|
|
||||||
case HSSFCell.CELL_TYPE_STRING :
|
case HSSFCell.CELL_TYPE_STRING :
|
||||||
value = cell.getRichStringCellValue().getString();
|
return cell.getRichStringCellValue().getString();
|
||||||
break;
|
|
||||||
|
|
||||||
case HSSFCell.CELL_TYPE_BOOLEAN :
|
case HSSFCell.CELL_TYPE_BOOLEAN :
|
||||||
value = String.valueOf(cell.getBooleanCellValue());
|
return String.valueOf(cell.getBooleanCellValue());
|
||||||
|
case HSSFCell.CELL_TYPE_BLANK :
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return value;
|
throw new RuntimeException("Unexpected celltype (" + cellType + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -587,23 +566,29 @@ public class HSSFDataFormatter {
|
|||||||
|
|
||||||
// Some custom formats
|
// Some custom formats
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a <tt>DecimalFormat</tt> with parseIntegerOnly set <code>true</code>
|
||||||
|
*/
|
||||||
|
/* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) {
|
||||||
|
DecimalFormat result = new DecimalFormat(fmt);
|
||||||
|
result.setParseIntegerOnly(true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Format class for Excel's SSN format. This class mimics Excel's built-in
|
* Format class for Excel's SSN format. This class mimics Excel's built-in
|
||||||
* SSN formatting.
|
* SSN formatting.
|
||||||
*
|
*
|
||||||
* @author James May
|
* @author James May
|
||||||
*/
|
*/
|
||||||
static class SSNFormat extends Format {
|
private static final class SSNFormat extends Format {
|
||||||
private DecimalFormat df;
|
public static final Format instance = new SSNFormat();
|
||||||
|
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
|
||||||
/** Constructor */
|
private SSNFormat() {
|
||||||
public SSNFormat() {
|
// enforce singleton
|
||||||
df = new DecimalFormat("000000000");
|
|
||||||
df.setParseIntegerOnly(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a number as an SSN */
|
/** Format a number as an SSN */
|
||||||
public String format(Number num) {
|
public static String format(Number num) {
|
||||||
String result = df.format(num);
|
String result = df.format(num);
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(result.substring(0, 3)).append('-');
|
sb.append(result.substring(0, 3)).append('-');
|
||||||
@ -612,8 +597,7 @@ public class HSSFDataFormatter {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuffer format(Object obj, StringBuffer toAppendTo,
|
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
FieldPosition pos) {
|
|
||||||
return toAppendTo.append(format((Number)obj));
|
return toAppendTo.append(format((Number)obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,17 +611,15 @@ public class HSSFDataFormatter {
|
|||||||
* built-in formatting for Zip + 4.
|
* built-in formatting for Zip + 4.
|
||||||
* @author James May
|
* @author James May
|
||||||
*/
|
*/
|
||||||
static class ZipPlusFourFormat extends Format {
|
private static final class ZipPlusFourFormat extends Format {
|
||||||
private DecimalFormat df;
|
public static final Format instance = new ZipPlusFourFormat();
|
||||||
|
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
|
||||||
/** Constructor */
|
private ZipPlusFourFormat() {
|
||||||
public ZipPlusFourFormat() {
|
// enforce singleton
|
||||||
df = new DecimalFormat("000000000");
|
|
||||||
df.setParseIntegerOnly(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a number as Zip + 4 */
|
/** Format a number as Zip + 4 */
|
||||||
public String format(Number num) {
|
public static String format(Number num) {
|
||||||
String result = df.format(num);
|
String result = df.format(num);
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(result.substring(0, 5)).append('-');
|
sb.append(result.substring(0, 5)).append('-');
|
||||||
@ -645,8 +627,7 @@ public class HSSFDataFormatter {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuffer format(Object obj, StringBuffer toAppendTo,
|
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
FieldPosition pos) {
|
|
||||||
return toAppendTo.append(format((Number)obj));
|
return toAppendTo.append(format((Number)obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,17 +641,15 @@ public class HSSFDataFormatter {
|
|||||||
* built-in phone number formatting.
|
* built-in phone number formatting.
|
||||||
* @author James May
|
* @author James May
|
||||||
*/
|
*/
|
||||||
static class PhoneFormat extends Format {
|
private static final class PhoneFormat extends Format {
|
||||||
private DecimalFormat df;
|
public static final Format instance = new PhoneFormat();
|
||||||
|
private static final DecimalFormat df = createIntegerOnlyFormat("##########");
|
||||||
/** Constructor */
|
private PhoneFormat() {
|
||||||
public PhoneFormat() {
|
// enforce singleton
|
||||||
df = new DecimalFormat("##########");
|
|
||||||
df.setParseIntegerOnly(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a number as a phone number */
|
/** Format a number as a phone number */
|
||||||
public String format(Number num) {
|
public static String format(Number num) {
|
||||||
String result = df.format(num);
|
String result = df.format(num);
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
String seg1, seg2, seg3;
|
String seg1, seg2, seg3;
|
||||||
@ -693,8 +672,7 @@ public class HSSFDataFormatter {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuffer format(Object obj, StringBuffer toAppendTo,
|
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
FieldPosition pos) {
|
|
||||||
return toAppendTo.append(format((Number)obj));
|
return toAppendTo.append(format((Number)obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ public class AllUserModelTests {
|
|||||||
result.addTestSuite(TestHSSFClientAnchor.class);
|
result.addTestSuite(TestHSSFClientAnchor.class);
|
||||||
result.addTestSuite(TestHSSFComment.class);
|
result.addTestSuite(TestHSSFComment.class);
|
||||||
result.addTestSuite(TestHSSFConditionalFormatting.class);
|
result.addTestSuite(TestHSSFConditionalFormatting.class);
|
||||||
|
result.addTestSuite(TestHSSFDataFormatter.class);
|
||||||
result.addTestSuite(TestHSSFDateUtil.class);
|
result.addTestSuite(TestHSSFDateUtil.class);
|
||||||
result.addTestSuite(TestHSSFHeaderFooter.class);
|
result.addTestSuite(TestHSSFHeaderFooter.class);
|
||||||
result.addTestSuite(TestHSSFHyperlink.class);
|
result.addTestSuite(TestHSSFHyperlink.class);
|
||||||
|
@ -29,10 +29,10 @@ import junit.framework.TestCase;
|
|||||||
* @author James May (james dot may at fmr dot com)
|
* @author James May (james dot may at fmr dot com)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestHSSFDataFormatter extends TestCase {
|
public final class TestHSSFDataFormatter extends TestCase {
|
||||||
|
|
||||||
HSSFDataFormatter formatter;
|
private final HSSFDataFormatter formatter;
|
||||||
HSSFWorkbook wb;
|
private final HSSFWorkbook wb;
|
||||||
|
|
||||||
public TestHSSFDataFormatter() {
|
public TestHSSFDataFormatter() {
|
||||||
// create the formatter to test
|
// create the formatter to test
|
||||||
@ -44,13 +44,13 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
HSSFDataFormat format = wb.createDataFormat();
|
HSSFDataFormat format = wb.createDataFormat();
|
||||||
|
|
||||||
// create a row and put some cells in it
|
// create a row and put some cells in it
|
||||||
HSSFRow row = sheet.createRow((short)0);
|
HSSFRow row = sheet.createRow(0);
|
||||||
|
|
||||||
// date value for July 8 1901 1:19 PM
|
// date value for July 8 1901 1:19 PM
|
||||||
double dateNum = 555.555;
|
double dateNum = 555.555;
|
||||||
|
|
||||||
//valid date formats -- all should have "Jul" in output
|
//valid date formats -- all should have "Jul" in output
|
||||||
String[] goodDatePatterns = new String[] {
|
String[] goodDatePatterns ={
|
||||||
"[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy",
|
"[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy",
|
||||||
"mmm/d/yy\\ h:mm PM;@",
|
"mmm/d/yy\\ h:mm PM;@",
|
||||||
"mmmm/d/yy\\ h:mm;@",
|
"mmmm/d/yy\\ h:mm;@",
|
||||||
@ -72,7 +72,7 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// valid number formats
|
// valid number formats
|
||||||
String[] goodNumPatterns = new String[] {
|
String[] goodNumPatterns = {
|
||||||
"#,##0.0000",
|
"#,##0.0000",
|
||||||
"#,##0;[Red]#,##0",
|
"#,##0;[Red]#,##0",
|
||||||
"(#,##0.00_);(#,##0.00)",
|
"(#,##0.00_);(#,##0.00)",
|
||||||
@ -86,7 +86,7 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// invalid date formats -- will throw exception in DecimalFormat ctor
|
// invalid date formats -- will throw exception in DecimalFormat ctor
|
||||||
String[] badNumPatterns = new String[] {
|
String[] badNumPatterns = {
|
||||||
"#,#$'#0.0000",
|
"#,#$'#0.0000",
|
||||||
"'#','#ABC#0;##,##0",
|
"'#','#ABC#0;##,##0",
|
||||||
"000 '123 4'5'6 000",
|
"000 '123 4'5'6 000",
|
||||||
@ -169,10 +169,10 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
// Valid date formats -- cell values should be date formatted & not "555.555"
|
// Valid date formats -- cell values should be date formatted & not "555.555"
|
||||||
HSSFRow row = wb.getSheetAt(0).getRow(0);
|
HSSFRow row = wb.getSheetAt(0).getRow(0);
|
||||||
Iterator it = row.cellIterator();
|
Iterator it = row.cellIterator();
|
||||||
System.out.println("==== VALID DATE FORMATS ====");
|
log("==== VALID DATE FORMATS ====");
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
HSSFCell cell = (HSSFCell) it.next();
|
HSSFCell cell = (HSSFCell) it.next();
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// should not be equal to "555.555"
|
// should not be equal to "555.555"
|
||||||
assertTrue( ! "555.555".equals(formatter.formatCellValue(cell)));
|
assertTrue( ! "555.555".equals(formatter.formatCellValue(cell)));
|
||||||
@ -184,10 +184,10 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
// test number formats
|
// test number formats
|
||||||
row = wb.getSheetAt(0).getRow(1);
|
row = wb.getSheetAt(0).getRow(1);
|
||||||
it = row.cellIterator();
|
it = row.cellIterator();
|
||||||
System.out.println("\n==== VALID NUMBER FORMATS ====");
|
log("\n==== VALID NUMBER FORMATS ====");
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
HSSFCell cell = (HSSFCell) it.next();
|
HSSFCell cell = (HSSFCell) it.next();
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// should not be equal to "1234567890.12345"
|
// should not be equal to "1234567890.12345"
|
||||||
assertTrue( ! "1234567890.12345".equals(formatter.formatCellValue(cell)));
|
assertTrue( ! "1234567890.12345".equals(formatter.formatCellValue(cell)));
|
||||||
@ -196,10 +196,10 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
// test bad number formats
|
// test bad number formats
|
||||||
row = wb.getSheetAt(0).getRow(2);
|
row = wb.getSheetAt(0).getRow(2);
|
||||||
it = row.cellIterator();
|
it = row.cellIterator();
|
||||||
System.out.println("\n==== INVALID NUMBER FORMATS ====");
|
log("\n==== INVALID NUMBER FORMATS ====");
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
HSSFCell cell = (HSSFCell) it.next();
|
HSSFCell cell = (HSSFCell) it.next();
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
// should be equal to "1234567890.12345"
|
// should be equal to "1234567890.12345"
|
||||||
assertEquals("1234567890.12345", formatter.formatCellValue(cell));
|
assertEquals("1234567890.12345", formatter.formatCellValue(cell));
|
||||||
}
|
}
|
||||||
@ -207,22 +207,22 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
// test Zip+4 format
|
// test Zip+4 format
|
||||||
row = wb.getSheetAt(0).getRow(3);
|
row = wb.getSheetAt(0).getRow(3);
|
||||||
HSSFCell cell = row.getCell(0);
|
HSSFCell cell = row.getCell(0);
|
||||||
System.out.println("\n==== ZIP FORMAT ====");
|
log("\n==== ZIP FORMAT ====");
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
assertEquals("12345-6789", formatter.formatCellValue(cell));
|
assertEquals("12345-6789", formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// test phone number format
|
// test phone number format
|
||||||
row = wb.getSheetAt(0).getRow(4);
|
row = wb.getSheetAt(0).getRow(4);
|
||||||
cell = row.getCell(0);
|
cell = row.getCell(0);
|
||||||
System.out.println("\n==== PHONE FORMAT ====");
|
log("\n==== PHONE FORMAT ====");
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
assertEquals("(555) 123-4567", formatter.formatCellValue(cell));
|
assertEquals("(555) 123-4567", formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// test SSN format
|
// test SSN format
|
||||||
row = wb.getSheetAt(0).getRow(5);
|
row = wb.getSheetAt(0).getRow(5);
|
||||||
cell = row.getCell(0);
|
cell = row.getCell(0);
|
||||||
System.out.println("\n==== SSN FORMAT ====");
|
log("\n==== SSN FORMAT ====");
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
assertEquals("444-55-1234", formatter.formatCellValue(cell));
|
assertEquals("444-55-1234", formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// null test-- null cell should result in empty String
|
// null test-- null cell should result in empty String
|
||||||
@ -237,17 +237,17 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
// test formula format
|
// test formula format
|
||||||
HSSFRow row = wb.getSheetAt(0).getRow(6);
|
HSSFRow row = wb.getSheetAt(0).getRow(6);
|
||||||
HSSFCell cell = row.getCell(0);
|
HSSFCell cell = row.getCell(0);
|
||||||
System.out.println("\n==== FORMULA CELL ====");
|
log("\n==== FORMULA CELL ====");
|
||||||
|
|
||||||
// first without a formula evaluator
|
// first without a formula evaluator
|
||||||
System.out.println(formatter.formatCellValue(cell) + "\t (without evaluator)");
|
log(formatter.formatCellValue(cell) + "\t (without evaluator)");
|
||||||
assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));
|
assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));
|
||||||
|
|
||||||
// now with a formula evaluator
|
// now with a formula evaluator
|
||||||
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
|
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
|
||||||
//! must set current row !
|
//! must set current row !
|
||||||
evaluator.setCurrentRow(row);
|
evaluator.setCurrentRow(row);
|
||||||
System.out.println(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
|
log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
|
||||||
assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
|
assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,20 +263,19 @@ public class TestHSSFDataFormatter extends TestCase {
|
|||||||
Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD");
|
Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD");
|
||||||
formatter.setDefaultNumberFormat(defaultFormat);
|
formatter.setDefaultNumberFormat(defaultFormat);
|
||||||
double value = 10d;
|
double value = 10d;
|
||||||
System.out.println("\n==== DEFAULT NUMBER FORMAT ====");
|
log("\n==== DEFAULT NUMBER FORMAT ====");
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
HSSFCell cell = (HSSFCell) it.next();
|
HSSFCell cell = (HSSFCell) it.next();
|
||||||
cell.setCellValue(cell.getNumericCellValue() * Math.random() / 1000000 - 1000);
|
cell.setCellValue(cell.getNumericCellValue() * Math.random() / 1000000 - 1000);
|
||||||
System.out.println(formatter.formatCellValue(cell));
|
log(formatter.formatCellValue(cell));
|
||||||
assertTrue(formatter.formatCellValue(cell).startsWith("Balance "));
|
assertTrue(formatter.formatCellValue(cell).startsWith("Balance "));
|
||||||
assertTrue(formatter.formatCellValue(cell).endsWith(" USD"));
|
assertTrue(formatter.formatCellValue(cell).endsWith(" USD"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String [] args) {
|
private static void log(String msg) {
|
||||||
System.out
|
if (false) { // successful tests should be silent
|
||||||
.println("Testing org.apache.poi.hssf.usermodel.TestHSSFDataFormatter");
|
System.out.println(msg);
|
||||||
junit.textui.TestRunner.run(TestHSSFDataFormatter.class);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user