diff options
author | Yegor Kozlov <yegor@apache.org> | 2011-05-19 12:00:10 +0000 |
---|---|---|
committer | Yegor Kozlov <yegor@apache.org> | 2011-05-19 12:00:10 +0000 |
commit | a50e57e58feda9b36a91879566f3e7ca922d67e1 (patch) | |
tree | 21ce4d71a8aa061c8fa0005c4a05a5f587e102d2 /src/ooxml/java | |
parent | cc2646c12a4bf49be4417d6c48a6892dd2956e95 (diff) | |
download | poi-a50e57e58feda9b36a91879566f3e7ca922d67e1.tar.gz poi-a50e57e58feda9b36a91879566f3e7ca922d67e1.zip |
improved test coverage for SXSSF
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1124698 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/ooxml/java')
5 files changed, 204 insertions, 55 deletions
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index fba4308ecc..b6423189ac 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -17,19 +17,16 @@ package org.apache.poi.xssf.streaming; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.formula.eval.ErrorEval; +import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.util.CellRangeAddress; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; /** * Streaming version of XSSFRow implementing the "BigGridDemo" strategy. @@ -132,9 +129,11 @@ public class SXSSFCell implements Cell */ public int getCachedFormulaResultType() { -//TODO: Implement this correctly - assert false; - return CELL_TYPE_NUMERIC; + if (_value.getType() != CELL_TYPE_FORMULA) { + throw new IllegalStateException("Only formula cells have cached results"); + } + + return ((FormulaValue)_value).getFormulaType(); } /** @@ -146,11 +145,19 @@ public class SXSSFCell implements Cell */ public void setCellValue(double value) { - ensureTypeOrFormulaType(CELL_TYPE_NUMERIC); - if(_value.getType()==CELL_TYPE_FORMULA) - ((NumericFormulaValue)_value).setPreEvaluatedValue(value); - else - ((NumericValue)_value).setValue(value); + if(Double.isInfinite(value)) { + // Excel does not support positive/negative infinities, + // rather, it gives a #DIV/0! error in these cases. + setCellErrorValue(FormulaError.DIV0.getCode()); + } else if (Double.isNaN(value)){ + setCellErrorValue(FormulaError.NUM.getCode()); + } else { + ensureTypeOrFormulaType(CELL_TYPE_NUMERIC); + if(_value.getType()==CELL_TYPE_FORMULA) + ((NumericFormulaValue)_value).setPreEvaluatedValue(value); + else + ((NumericValue)_value).setValue(value); + } } /** @@ -244,6 +251,11 @@ public class SXSSFCell implements Cell */ public void setCellFormula(String formula) throws FormulaParseException { + if(formula == null) { + setType(Cell.CELL_TYPE_BLANK); + return; + } + ensureFormulaType(computeTypeFromFormula(formula)); ((FormulaValue)_value).setValue(formula); } @@ -328,9 +340,16 @@ public class SXSSFCell implements Cell public RichTextString getRichStringCellValue() { int cellType = getCellType(); - if(!(getCellType()==CELL_TYPE_STRING&&((StringValue)_value).isRichText())) + if(getCellType() != CELL_TYPE_STRING) throw typeMismatch(CELL_TYPE_STRING, cellType, false); - return ((RichTextValue)_value).getValue(); + + StringValue sval = (StringValue)_value; + if(sval.isRichText()) + return ((RichTextValue)_value).getValue(); + else { + String plainText = getStringCellValue(); + return getSheet().getWorkbook().getCreationHelper().createRichTextString(plainText); + } } @@ -490,7 +509,12 @@ public class SXSSFCell implements Cell */ public CellStyle getCellStyle() { - return _style; + if(_style == null){ + SXSSFWorkbook wb = (SXSSFWorkbook)getRow().getSheet().getWorkbook(); + return wb.getCellStyleAt((short)0); + } else { + return _style; + } } /** @@ -569,6 +593,37 @@ public class SXSSFCell implements Cell } //end of interface implementation + /** + * Returns a string representation of the cell + * <p> + * Formula cells return the formula string, rather than the formula result. + * Dates are displayed in dd-MMM-yyyy format + * Errors are displayed as #ERR<errIdx> + * </p> + */ + public String toString() { + switch (getCellType()) { + case CELL_TYPE_BLANK: + return ""; + case CELL_TYPE_BOOLEAN: + return getBooleanCellValue() ? "TRUE" : "FALSE"; + case CELL_TYPE_ERROR: + return ErrorEval.getText(getErrorCellValue()); + case CELL_TYPE_FORMULA: + return getCellFormula(); + case CELL_TYPE_NUMERIC: + if (DateUtil.isCellDateFormatted(this)) { + DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); + return sdf.format(getDateCellValue()); + } + return getNumericCellValue() + ""; + case CELL_TYPE_STRING: + return getRichStringCellValue().toString(); + default: + return "Unknown Cell Type: " + getCellType(); + } + } + void removeProperty(int type) { Property current=_firstProperty; @@ -693,7 +748,13 @@ public class SXSSFCell implements Cell } case CELL_TYPE_STRING: { - _value=new PlainStringValue(); + PlainStringValue sval = new PlainStringValue(); + if(_value != null){ + // if a cell is not blank then convert the old value to string + String str = convertCellValueToString(); + sval.setValue(str); + } + _value = sval; break; } case CELL_TYPE_FORMULA: @@ -708,7 +769,13 @@ public class SXSSFCell implements Cell } case CELL_TYPE_BOOLEAN: { - _value=new BooleanValue(); + BooleanValue bval = new BooleanValue(); + if(_value != null){ + // if a cell is not blank then convert the old value to string + boolean val = convertCellValueToBoolean(); + bval.setValue(val); + } + _value = bval; break; } case CELL_TYPE_ERROR: @@ -781,6 +848,49 @@ public class SXSSFCell implements Cell } return "#unknown cell type (" + cellTypeCode + ")#"; } + private boolean convertCellValueToBoolean() { + int cellType = getCellType(); + + if (cellType == CELL_TYPE_FORMULA) { + cellType = getCachedFormulaResultType(); + } + + switch (cellType) { + case CELL_TYPE_BOOLEAN: + return getBooleanCellValue(); + case CELL_TYPE_STRING: + + String text = getStringCellValue(); + return Boolean.parseBoolean(text); + case CELL_TYPE_NUMERIC: + return getNumericCellValue() != 0; + case CELL_TYPE_ERROR: + case CELL_TYPE_BLANK: + return false; + } + throw new RuntimeException("Unexpected cell type (" + cellType + ")"); + } + private String convertCellValueToString() { + int cellType = getCellType(); + + switch (cellType) { + case CELL_TYPE_BLANK: + return ""; + case CELL_TYPE_BOOLEAN: + return getBooleanCellValue() ? "TRUE" : "FALSE"; + case CELL_TYPE_STRING: + return getStringCellValue(); + case CELL_TYPE_NUMERIC: + case CELL_TYPE_ERROR: + byte errVal = getErrorCellValue(); + return FormulaError.forInt(errVal).getString(); + case CELL_TYPE_FORMULA: + return ""; + default: + throw new IllegalStateException("Unexpected cell type (" + cellType + ")"); + } + } + //END OF COPIED CODE static abstract class Property @@ -870,7 +980,7 @@ public class SXSSFCell implements Cell return false; } } - static class RichTextValue implements Value + static class RichTextValue extends StringValue { RichTextString _value; public int getType() diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java index 25808c9c5f..ad7383661c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java @@ -35,8 +35,7 @@ public class SXSSFRow implements Row SXSSFCell[] _cells; int _maxColumn=-1; short _height=-1; -//TODO: Need to set the correct default value for _zHeight - boolean _zHeight; + boolean _zHeight = false; public SXSSFRow(SXSSFSheet sheet, int initialSize) { @@ -150,9 +149,29 @@ public class SXSSFRow implements Row * @return Cell representing that column or null if undefined. * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy) */ - public Cell getCell(int cellnum) - { - return cellnum>_maxColumn?null:_cells[cellnum]; + public Cell getCell(int cellnum) { + if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0"); + + Cell cell = cellnum > _maxColumn ? null : _cells[cellnum]; + + MissingCellPolicy policy = _sheet.getWorkbook().getMissingCellPolicy(); + if(policy == RETURN_NULL_AND_BLANK) { + return cell; + } + if (policy == RETURN_BLANK_AS_NULL) { + if (cell == null) return cell; + if (cell.getCellType() == Cell.CELL_TYPE_BLANK) { + return null; + } + return cell; + } + if (policy == CREATE_NULL_AS_BLANK) { + if (cell == null) { + return createCell((short) cellnum, Cell.CELL_TYPE_BLANK); + } + return cell; + } + throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")"); } /** @@ -226,7 +245,7 @@ public class SXSSFRow implements Row */ public short getLastCellNum() { - return (short)(_maxColumn+1); + return _maxColumn == -1 ? -1 : (short)(_maxColumn+1); } /** @@ -337,6 +356,16 @@ public class SXSSFRow implements Row public class FilledCellIterator implements Iterator<Cell> { int pos=0; + + FilledCellIterator(){ + for (int i = 0; i <= _maxColumn; i++) { + if (_cells[i] != null) { + pos = i; + break; + } + } + } + public boolean hasNext() { return pos <= _maxColumn; diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index 86ac777844..be90606e1b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -27,20 +27,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.PrintSetup; -import org.apache.poi.ss.usermodel.Header; -import org.apache.poi.ss.usermodel.Footer; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.AutoFilter; +import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -125,6 +112,10 @@ public class SXSSFSheet implements Sheet, Cloneable */ public void removeRow(Row row) { + if (row.getSheet() != this) { + throw new IllegalArgumentException("Specified row does not belong to this sheet"); + } + for(Iterator<Map.Entry<Integer,SXSSFRow>> iter=_rows.entrySet().iterator();iter.hasNext();) { Map.Entry<Integer,SXSSFRow> entry=iter.next(); @@ -165,10 +156,9 @@ public class SXSSFSheet implements Sheet, Cloneable */ public int getFirstRowNum() { - if(_writer.getNumberOfFlushedRows()>0) + if(_writer.getNumberOfFlushedRows() > 0) return _writer.getLowestIndexOfFlushedRows(); - Integer firstKey=_rows.firstKey(); - return firstKey==null?-1:firstKey.intValue(); + return _rows.size() == 0 ? 0 : _rows.firstKey(); } /** @@ -178,8 +168,7 @@ public class SXSSFSheet implements Sheet, Cloneable */ public int getLastRowNum() { - Integer lastKey=_rows.lastKey(); - return lastKey==null?-1:lastKey.intValue(); + return _rows.size() == 0 ? 0 : _rows.lastKey(); } /** @@ -1306,6 +1295,8 @@ public class SXSSFSheet implements Sheet, Cloneable _out.write("<row r=\""+(rownum+1)+"\""); if(row.hasCustomHeight()) _out.write(" customHeight=\"true\" ht=\""+row.getHeightInPoints()+"\""); + if(row.getZeroHeight()) + _out.write(" hidden=\"true\""); _out.write(">\n"); this._rownum = rownum; _rowContainedNullCells=false; @@ -1326,17 +1317,30 @@ public class SXSSFSheet implements Sheet, Cloneable String ref = new CellReference(_rownum, columnIndex).formatAsString(); _out.write("<c r=\""+ref+"\""); CellStyle cellStyle=cell.getCellStyle(); - if(cellStyle!=null) _out.write(" s=\""+cellStyle.getIndex()+"\""); + if(cellStyle.getIndex() != 0) _out.write(" s=\""+cellStyle.getIndex()+"\""); int cellType=cell.getCellType(); switch(cellType) { case Cell.CELL_TYPE_BLANK: { -//TODO: What needs to be done here? + _out.write(">"); + break; } case Cell.CELL_TYPE_FORMULA: { -//TODO: What needs to be done here? + _out.write(">"); + _out.write("<f>"); + outputQuotedString(cell.getCellFormula()); + _out.write("</f>"); + switch (cell.getCachedFormulaResultType()){ + case Cell.CELL_TYPE_NUMERIC: + double nval = cell.getNumericCellValue(); + if(!Double.isNaN(nval)){ + _out.write("<v>"+nval+"</v>"); + } + break; + } + break; } case Cell.CELL_TYPE_STRING: { @@ -1354,15 +1358,16 @@ public class SXSSFSheet implements Sheet, Cloneable } case Cell.CELL_TYPE_BOOLEAN: { - _out.write(" t=\"n\">"); + _out.write(" t=\"b\">"); _out.write("<v>"+(cell.getBooleanCellValue()?"1":"0")+"</v>"); break; } case Cell.CELL_TYPE_ERROR: { -//TODO: What needs to be done here? - _out.write(" t=\"inlineStr\">"); - _out.write("<is><t></t></is>"); + FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); + + _out.write(" t=\"e\">"); + _out.write("<v>" + error.getString() +"</v>"); break; } default: diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 95678f3fc1..aa17b536a0 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -327,7 +327,7 @@ public class SXSSFWorkbook implements Workbook */ public Sheet cloneSheet(int sheetNum) { - return createAndRegisterSXSSFSheet(_wb.cloneSheet(sheetNum)); + throw new RuntimeException("NotImplemented"); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java index 3f8ce85a63..77981db301 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java @@ -256,6 +256,11 @@ public class XSSFFormulaEvaluator implements FormulaEvaluator { * Returns a CellValue wrapper around the supplied ValueEval instance. */ private CellValue evaluateFormulaCellValue(Cell cell) { + if(!(cell instanceof XSSFCell)){ + throw new IllegalArgumentException("Unexpected type of cell: " + cell.getClass() + "." + + " Only XSSFCells can be evaluated."); + } + ValueEval eval = _bookEvaluator.evaluate(new XSSFEvaluationCell((XSSFCell) cell)); if (eval instanceof NumberEval) { NumberEval ne = (NumberEval) eval; |