Fix for bug 44708. XSSFCell.getCellType() now returns CELL_TYPE_BLANK for numeric cells with no value.

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@645298 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-04-06 20:27:40 +00:00
parent f3aa6517c0
commit 4e01cda4ae
7 changed files with 327 additions and 156 deletions

View File

@ -236,6 +236,7 @@ under the License.
<path refid="ooxml.classpath"/> <path refid="ooxml.classpath"/>
<pathelement location="${ooxml.output.dir}"/> <pathelement location="${ooxml.output.dir}"/>
<pathelement location="${ooxml.output.test.dir}"/> <pathelement location="${ooxml.output.test.dir}"/>
<pathelement location="${main.output.test.dir}"/> <!-- ooxml tests use some utilities from main tests -->
<pathelement location="${junit.jar1.dir}"/> <pathelement location="${junit.jar1.dir}"/>
</path> </path>
@ -790,7 +791,7 @@ under the License.
<batchtest todir="${ooxml.reports.test}"> <batchtest todir="${ooxml.reports.test}">
<fileset dir="${ooxml.src.test}"> <fileset dir="${ooxml.src.test}">
<include name="**/Test*.java"/> <include name="**/Test*.java"/>
<exclude name="**/AllTests.java"/> <exclude name="**/All*Tests.java"/>
</fileset> </fileset>
</batchtest> </batchtest>
</junit> </junit>

View File

@ -117,11 +117,12 @@ public interface Cell {
void setCellType(int cellType); void setCellType(int cellType);
/** /**
* get the cells type (numeric, formula or string) * @return the cell's type (e.g. numeric, formula or string)
* @see #CELL_TYPE_STRING * @see #CELL_TYPE_STRING
* @see #CELL_TYPE_NUMERIC * @see #CELL_TYPE_NUMERIC
* @see #CELL_TYPE_FORMULA * @see #CELL_TYPE_FORMULA
* @see #CELL_TYPE_BOOLEAN * @see #CELL_TYPE_BOOLEAN
* @see #CELL_TYPE_BLANK
* @see #CELL_TYPE_ERROR * @see #CELL_TYPE_ERROR
*/ */

View File

@ -35,8 +35,10 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType;
/**
public class XSSFCell implements Cell { *
*/
public final class XSSFCell implements Cell {
private static final String FALSE_AS_STRING = "0"; private static final String FALSE_AS_STRING = "0";
private static final String TRUE_AS_STRING = "1"; private static final String TRUE_AS_STRING = "1";
@ -45,9 +47,9 @@ public class XSSFCell implements Cell {
private int cellNum; private int cellNum;
private SharedStringSource sharedStringSource; private SharedStringSource sharedStringSource;
private StylesSource stylesSource; private StylesSource stylesSource;
private POILogger logger = POILogFactory.getLogger(XSSFCell.class); private POILogger logger = POILogFactory.getLogger(XSSFCell.class);
/** /**
* Create a new XSSFCell. This method is protected to be used only by * Create a new XSSFCell. This method is protected to be used only by
* tests. * tests.
@ -55,7 +57,7 @@ public class XSSFCell implements Cell {
protected XSSFCell(XSSFRow row) { protected XSSFCell(XSSFRow row) {
this(row, CTCell.Factory.newInstance()); this(row, CTCell.Factory.newInstance());
} }
public XSSFCell(XSSFRow row, CTCell cell) { public XSSFCell(XSSFRow row, CTCell cell) {
this.cell = cell; this.cell = cell;
this.row = row; this.row = row;
@ -65,31 +67,31 @@ public class XSSFCell implements Cell {
this.sharedStringSource = row.getSheet().getWorkbook().getSharedStringSource(); this.sharedStringSource = row.getSheet().getWorkbook().getSharedStringSource();
this.stylesSource = row.getSheet().getWorkbook().getStylesSource(); this.stylesSource = row.getSheet().getWorkbook().getStylesSource();
} }
protected SharedStringSource getSharedStringSource() { protected SharedStringSource getSharedStringSource() {
return this.sharedStringSource; return this.sharedStringSource;
} }
protected StylesSource getStylesSource() { protected StylesSource getStylesSource() {
return this.stylesSource; return this.stylesSource;
} }
public boolean getBooleanCellValue() { public boolean getBooleanCellValue() {
if (STCellType.B != cell.getT()) { if (STCellType.B != cell.getT()) {
throw new NumberFormatException("You cannot get a boolean value from a non-boolean cell"); throw new NumberFormatException("You cannot get a boolean value from a non-boolean cell");
} }
if (cell.isSetV()) { if (cell.isSetV()) {
return (TRUE_AS_STRING.equals(this.cell.getV())); return (TRUE_AS_STRING.equals(this.cell.getV()));
} }
return false; return false;
} }
public Comment getCellComment() { public Comment getCellComment() {
return row.getSheet().getCellComment(row.getRowNum(), getCellNum()); return row.getSheet().getCellComment(row.getRowNum(), getCellNum());
} }
public String getCellFormula() { public String getCellFormula() {
if(this.cell.getF() == null) { if(this.cell.getF() == null) {
throw new NumberFormatException("You cannot get a formula from a non-formula cell"); throw new NumberFormatException("You cannot get a formula from a non-formula cell");
} }
return this.cell.getF().getStringValue(); return this.cell.getF().getStringValue();
@ -100,24 +102,32 @@ public class XSSFCell implements Cell {
} }
public CellStyle getCellStyle() { public CellStyle getCellStyle() {
// Zero is the empty default // Zero is the empty default
if(this.cell.getS() > 0) { if(this.cell.getS() > 0) {
return stylesSource.getStyleAt(this.cell.getS()); return stylesSource.getStyleAt(this.cell.getS());
} }
return null; return null;
} }
public int getCellType() { public int getCellType() {
// Detecting formulas is quite pesky, // Detecting formulas is quite pesky,
// as they don't get their type set // as they don't get their type set
if(this.cell.getF() != null) { if(this.cell.getF() != null) {
return CELL_TYPE_FORMULA; return CELL_TYPE_FORMULA;
} }
switch (this.cell.getT().intValue()) { switch (this.cell.getT().intValue()) {
case STCellType.INT_B: case STCellType.INT_B:
return CELL_TYPE_BOOLEAN; return CELL_TYPE_BOOLEAN;
case STCellType.INT_N: case STCellType.INT_N:
if(!cell.isSetV()) {
// ooxml does have a separate cell type of 'blank'. A blank cell gets encoded as
// (either not present or) a numeric cell with no value set.
// The formula evaluator (and perhaps other clients of this interface) needs to
// distinguish blank values which sometimes get translated into zero and sometimes
// empty string, depending on context
return CELL_TYPE_BLANK;
}
return CELL_TYPE_NUMERIC; return CELL_TYPE_NUMERIC;
case STCellType.INT_E: case STCellType.INT_E:
return CELL_TYPE_ERROR; return CELL_TYPE_ERROR;
@ -148,11 +158,11 @@ public class XSSFCell implements Cell {
* Returns the error message, such as #VALUE! * Returns the error message, such as #VALUE!
*/ */
public String getErrorCellString() { public String getErrorCellString() {
if (STCellType.E != cell.getT()) { if (STCellType.E != cell.getT()) {
throw new NumberFormatException("You cannot get a error value from a non-error cell"); throw new NumberFormatException("You cannot get a error value from a non-error cell");
} }
if (this.cell.isSetV()) { if (this.cell.isSetV()) {
return this.cell.getV(); return this.cell.getV();
} }
return null; return null;
} }
@ -161,42 +171,59 @@ public class XSSFCell implements Cell {
* HSSFCell does. See {@link Cell} for details * HSSFCell does. See {@link Cell} for details
*/ */
public byte getErrorCellValue() { public byte getErrorCellValue() {
if (STCellType.E != cell.getT()) { if (STCellType.E != cell.getT()) {
throw new NumberFormatException("You cannot get a error value from a non-error cell"); throw new NumberFormatException("You cannot get a error value from a non-error cell");
} }
if (this.cell.isSetV()) { if (this.cell.isSetV()) {
String errS = this.cell.getV(); String errS = this.cell.getV();
if(errS.equals(Cell.ERROR_NULL.getStringRepr())) { if(errS.equals(Cell.ERROR_NULL.getStringRepr())) {
return Cell.ERROR_NULL.getType(); return Cell.ERROR_NULL.getType();
} }
if(errS.equals(Cell.ERROR_DIV0.getStringRepr())) { if(errS.equals(Cell.ERROR_DIV0.getStringRepr())) {
return Cell.ERROR_DIV0.getType(); return Cell.ERROR_DIV0.getType();
} }
if(errS.equals(Cell.ERROR_VALUE.getStringRepr())) { if(errS.equals(Cell.ERROR_VALUE.getStringRepr())) {
return Cell.ERROR_VALUE.getType(); return Cell.ERROR_VALUE.getType();
} }
if(errS.equals(Cell.ERROR_REF.getStringRepr())) { if(errS.equals(Cell.ERROR_REF.getStringRepr())) {
return Cell.ERROR_REF.getType(); return Cell.ERROR_REF.getType();
} }
if(errS.equals(Cell.ERROR_NAME.getStringRepr())) { if(errS.equals(Cell.ERROR_NAME.getStringRepr())) {
return Cell.ERROR_NAME.getType(); return Cell.ERROR_NAME.getType();
} }
if(errS.equals(Cell.ERROR_NUM.getStringRepr())) { if(errS.equals(Cell.ERROR_NUM.getStringRepr())) {
return Cell.ERROR_NUM.getType(); return Cell.ERROR_NUM.getType();
} }
return Cell.ERROR_NA.getType(); return Cell.ERROR_NA.getType();
} }
return 0; return 0;
} }
public double getNumericCellValue() { public double getNumericCellValue() {
if (STCellType.N != cell.getT() && STCellType.STR != cell.getT()) { if (STCellType.N != cell.getT() && STCellType.STR != cell.getT()) {
throw new NumberFormatException("You cannot get a numeric value from a non-numeric cell"); throw new NumberFormatException("You cannot get a numeric value from a non-numeric cell");
} }
if (this.cell.isSetV()) { if (this.cell.isSetV()) {
return Double.parseDouble(this.cell.getV()); return Double.parseDouble(this.cell.getV());
} }
return Double.NaN; // else - cell is blank.
// TODO - behaviour in the case of blank cells.
// Revise spec, choose best alternative below, and comment why.
if (true) {
// returning NaN from a blank cell seems wrong
// there are a few junits which assert this behaviour, though.
return Double.NaN;
}
if (true) {
// zero is probably a more reasonable value.
return 0.0;
} else {
// or perhaps disallow reading value from blank cell.
throw new RuntimeException("You cannot get a numeric value from a blank cell");
}
// Note - it would be nice if the behaviour is consistent with getRichStringCellValue
// (i.e. whether to return empty string or throw exception).
} }
public RichTextString getRichStringCellValue() { public RichTextString getRichStringCellValue() {
@ -219,34 +246,34 @@ public class XSSFCell implements Cell {
} }
public void setAsActiveCell() { public void setAsActiveCell() {
row.getSheet().setActiveCell(cell.getR()); row.getSheet().setActiveCell(cell.getR());
} }
public void setCellComment(Comment comment) { public void setCellComment(Comment comment) {
String cellRef = String cellRef =
new CellReference(row.getRowNum(), getCellNum()).formatAsString(); new CellReference(row.getRowNum(), getCellNum()).formatAsString();
row.getSheet().setCellComment(cellRef, (XSSFComment)comment); row.getSheet().setCellComment(cellRef, (XSSFComment)comment);
} }
public void setCellErrorValue(byte value) { public void setCellErrorValue(byte value) {
if(value == Cell.ERROR_DIV0.getType()) { if(value == Cell.ERROR_DIV0.getType()) {
setCellErrorValue(Cell.ERROR_DIV0); setCellErrorValue(Cell.ERROR_DIV0);
} else if(value == Cell.ERROR_NA.getType()) { } else if(value == Cell.ERROR_NA.getType()) {
setCellErrorValue(Cell.ERROR_NA); setCellErrorValue(Cell.ERROR_NA);
} else if(value == Cell.ERROR_NAME.getType()) { } else if(value == Cell.ERROR_NAME.getType()) {
setCellErrorValue(Cell.ERROR_NAME); setCellErrorValue(Cell.ERROR_NAME);
} else if(value == Cell.ERROR_NULL.getType()) { } else if(value == Cell.ERROR_NULL.getType()) {
setCellErrorValue(Cell.ERROR_NULL); setCellErrorValue(Cell.ERROR_NULL);
} else if(value == Cell.ERROR_NUM.getType()) { } else if(value == Cell.ERROR_NUM.getType()) {
setCellErrorValue(Cell.ERROR_NUM); setCellErrorValue(Cell.ERROR_NUM);
} else if(value == Cell.ERROR_REF.getType()) { } else if(value == Cell.ERROR_REF.getType()) {
setCellErrorValue(Cell.ERROR_REF); setCellErrorValue(Cell.ERROR_REF);
} else if(value == Cell.ERROR_VALUE.getType()) { } else if(value == Cell.ERROR_VALUE.getType()) {
setCellErrorValue(Cell.ERROR_VALUE); setCellErrorValue(Cell.ERROR_VALUE);
} else { } else {
logger.log(POILogger.WARN, "Unknown error type " + value + " specified, treating as #N/A"); logger.log(POILogger.WARN, "Unknown error type " + value + " specified, treating as #N/A");
setCellErrorValue(Cell.ERROR_NA); setCellErrorValue(Cell.ERROR_NA);
} }
} }
public void setCellErrorValue(CELL_ERROR_TYPE errorType) { public void setCellErrorValue(CELL_ERROR_TYPE errorType) {
if ((this.cell.getT() != STCellType.E) && (this.cell.getT() != STCellType.STR)) if ((this.cell.getT() != STCellType.E) && (this.cell.getT() != STCellType.STR))
@ -255,8 +282,8 @@ public class XSSFCell implements Cell {
} }
this.cell.setV( errorType.getStringRepr() ); this.cell.setV( errorType.getStringRepr() );
} }
public void setCellFormula(String formula) { public void setCellFormula(String formula) {
if (this.cell.getT() != STCellType.STR) if (this.cell.getT() != STCellType.STR)
{ {
@ -269,11 +296,11 @@ public class XSSFCell implements Cell {
if (this.cell.isSetV()) { if (this.cell.isSetV()) {
this.cell.unsetV(); this.cell.unsetV();
} }
} }
public void setCellNum(int num) { public void setCellNum(int num) {
setCellNum((short)num); setCellNum((short)num);
} }
public void setCellNum(short num) { public void setCellNum(short num) {
checkBounds(num); checkBounds(num);
@ -303,13 +330,13 @@ public class XSSFCell implements Cell {
} }
public void setCellStyle(CellStyle style) { public void setCellStyle(CellStyle style) {
if(style == null) { if(style == null) {
this.cell.setS(0); this.cell.setS(0);
} else { } else {
this.cell.setS( this.cell.setS(
row.getSheet().getWorkbook().getStylesSource().putStyle(style) row.getSheet().getWorkbook().getStylesSource().putStyle(style)
); );
} }
} }
public void setCellType(int cellType) { public void setCellType(int cellType) {
@ -364,7 +391,7 @@ public class XSSFCell implements Cell {
if ((this.cell.getT() != STCellType.B) && (this.cell.getT() != STCellType.STR)) if ((this.cell.getT() != STCellType.B) && (this.cell.getT() != STCellType.STR))
{ {
this.cell.setT(STCellType.B); this.cell.setT(STCellType.B);
} }
this.cell.setV(value ? TRUE_AS_STRING : FALSE_AS_STRING); this.cell.setV(value ? TRUE_AS_STRING : FALSE_AS_STRING);
} }
@ -372,12 +399,12 @@ public class XSSFCell implements Cell {
public String toString() { public String toString() {
return "[" + this.row.getRowNum() + "," + this.getCellNum() + "] " + this.cell.getV(); return "[" + this.row.getRowNum() + "," + this.getCellNum() + "] " + this.cell.getV();
} }
/** /**
* Returns the raw, underlying ooxml value for the cell * Returns the raw, underlying ooxml value for the cell
*/ */
public String getRawValue() { public String getRawValue() {
return this.cell.getV(); return this.cell.getV();
} }
/** /**
@ -396,14 +423,14 @@ public class XSSFCell implements Cell {
/** /**
* Creates an XSSFRichTextString for you. * Creates an XSSFRichTextString for you.
*/ */
public RichTextString createRichTextString(String text) { public RichTextString createRichTextString(String text) {
return new XSSFRichTextString(text); return new XSSFRichTextString(text);
} }
public Hyperlink getHyperlink() { public Hyperlink getHyperlink() {
return row.getSheet().getHyperlink(row.getRowNum(), cellNum); return row.getSheet().getHyperlink(row.getRowNum(), cellNum);
} }
public void setHyperlink(Hyperlink hyperlink) { public void setHyperlink(Hyperlink hyperlink) {
row.getSheet().setCellHyperlink((XSSFHyperlink)hyperlink); row.getSheet().setCellHyperlink((XSSFHyperlink)hyperlink);
} }
} }

View File

@ -0,0 +1,54 @@
/* ====================================================================
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.xssf;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.poi.xssf.eventusermodel.TestXSSFReader;
import org.apache.poi.xssf.extractor.TestXSSFExcelExtractor;
import org.apache.poi.xssf.io.TestLoadSaveXSSF;
import org.apache.poi.xssf.model.TestCommentsTable;
import org.apache.poi.xssf.model.TestStylesTable;
import org.apache.poi.xssf.usermodel.AllXSSFUsermodelTests;
import org.apache.poi.xssf.util.TestCTColComparator;
import org.apache.poi.xssf.util.TestCellReference;
import org.apache.poi.xssf.util.TestNumericRanges;
/**
* Collects all tests for <tt>org.apache.poi.xssf</tt> and sub-packages.
*
* @author Josh Micich
*/
public final class AllXSSFTests {
public static Test suite() {
TestSuite result = new TestSuite(AllXSSFTests.class.getName());
result.addTest(AllXSSFUsermodelTests.suite());
result.addTestSuite(TestXSSFReader.class);
result.addTestSuite(TestXSSFExcelExtractor.class);
result.addTestSuite(TestLoadSaveXSSF.class);
result.addTestSuite(TestCommentsTable.class);
result.addTestSuite(TestStylesTable.class);
result.addTestSuite(TestCellReference.class);
result.addTestSuite(TestCTColComparator.class);
result.addTestSuite(TestNumericRanges.class);
return result;
}
}

View File

@ -0,0 +1,56 @@
/* ====================================================================
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.xssf.usermodel;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.poi.xssf.usermodel.extensions.TestXSSFBorder;
import org.apache.poi.xssf.usermodel.extensions.TestXSSFCellFill;
import org.apache.poi.xssf.usermodel.extensions.TestXSSFSheetComments;
import org.apache.poi.xssf.usermodel.helpers.TestColumnHelper;
import org.apache.poi.xssf.usermodel.helpers.TestHeaderFooterHelper;
/**
* Collects all tests for <tt>org.apache.poi.xssf.usermodel</tt> and sub-packages.
*
* @author Josh Micich
*/
public final class AllXSSFUsermodelTests {
public static Test suite() {
TestSuite result = new TestSuite(AllXSSFUsermodelTests.class.getName());
result.addTestSuite(TestXSSFBorder.class);
result.addTestSuite(TestXSSFCellFill.class);
result.addTestSuite(TestXSSFHeaderFooter.class);
result.addTestSuite(TestXSSFSheetComments.class);
result.addTestSuite(TestColumnHelper.class);
result.addTestSuite(TestHeaderFooterHelper.class);
result.addTestSuite(TestFormulaEvaluatorOnXSSF.class);
result.addTestSuite(TestXSSFCell.class);
result.addTestSuite(TestXSSFCellStyle.class);
result.addTestSuite(TestXSSFComment.class);
result.addTestSuite(TestXSSFDialogSheet.class);
result.addTestSuite(TestXSSFFormulaEvaluation.class);
result.addTestSuite(TestXSSFHeaderFooter.class);
result.addTestSuite(TestXSSFRow.class);
result.addTestSuite(TestXSSFSheet.class);
result.addTestSuite(TestXSSFWorkbook.class);
return result;
}
}

View File

@ -41,7 +41,6 @@ import org.openxml4j.opc.Package;
* Periodically, you should open FormulaEvalTestData.xls in * Periodically, you should open FormulaEvalTestData.xls in
* Excel 2007, and re-save it as FormulaEvalTestData_Copy.xlsx * Excel 2007, and re-save it as FormulaEvalTestData_Copy.xlsx
* *
* Currently disabled, as doesn't work
*/ */
public final class TestFormulaEvaluatorOnXSSF extends TestCase { public final class TestFormulaEvaluatorOnXSSF extends TestCase {
@ -178,7 +177,7 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase {
* Disabled for now, as many things seem to break * Disabled for now, as many things seem to break
* for XSSF, which is a shame * for XSSF, which is a shame
*/ */
public void DISABLEDtestFunctionsFromTestSpreadsheet() { public void testFunctionsFromTestSpreadsheet() {
processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null); processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null);
processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null); processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null);
@ -261,8 +260,19 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase {
if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) { if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) {
continue; continue;
} }
if(isIgnoredFormulaTestCase(c.getCellFormula())) {
continue;
}
FormulaEvaluator.CellValue actualValue = evaluator.evaluate(c); FormulaEvaluator.CellValue actualValue;
try {
actualValue = evaluator.evaluate(c);
} catch (RuntimeException e) {
_evaluationFailureCount ++;
printShortStackTrace(System.err, e);
result = Result.SOME_EVALUATIONS_FAILED;
continue;
}
Cell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum); Cell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum);
try { try {
@ -281,10 +291,29 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase {
return result; return result;
} }
/*
* TODO - these are all formulas which currently (Apr-2008) break on ooxml
*/
private static boolean isIgnoredFormulaTestCase(String cellFormula) {
if ("COLUMN(1:2)".equals(cellFormula) || "ROW(2:3)".equals(cellFormula)) {
// full row ranges are not parsed properly yet.
// These cases currently work in svn trunk because of another bug which causes the
// formula to get rendered as COLUMN($A$1:$IV$2) or ROW($A$2:$IV$3)
return true;
}
if ("ISREF(currentcell())".equals(cellFormula)) {
// currently throws NPE because unknown function "currentcell" causes name lookup
// Name lookup requires some equivalent object of the Workbook within xSSFWorkbook.
return true;
}
return false;
}
/** /**
* Useful to keep output concise when expecting many failures to be reported by this test case * Useful to keep output concise when expecting many failures to be reported by this test case
*/ */
private static void printShortStackTrace(PrintStream ps, AssertionFailedError e) { private static void printShortStackTrace(PrintStream ps, Throwable e) {
StackTraceElement[] stes = e.getStackTrace(); StackTraceElement[] stes = e.getStackTrace();
int startIx = 0; int startIx = 0;

View File

@ -24,43 +24,45 @@ import junit.framework.TestCase;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.TestXSSFCell.DummySharedStringSource; import org.apache.poi.xssf.usermodel.TestXSSFCell.DummySharedStringSource;
/**
public class TestXSSFRow extends TestCase { * Tests for XSSFRow
*/
public final class TestXSSFRow extends TestCase {
/** /**
* Test adding cells to a row in various places and see if we can find them again. * Test adding cells to a row in various places and see if we can find them again.
*/ */
public void testAddAndIterateCells() { public void testAddAndIterateCells() {
XSSFRow row = new XSSFRow(createParentObjects()); XSSFRow row = new XSSFRow(createParentObjects());
// One cell at the beginning // One cell at the beginning
Cell cell1 = row.createCell((short) 1); Cell cell1 = row.createCell((short) 1);
Iterator<Cell> it = row.cellIterator(); Iterator<Cell> it = row.cellIterator();
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell1 == it.next()); assertTrue(cell1 == it.next());
assertFalse(it.hasNext()); assertFalse(it.hasNext());
// Add another cell at the end // Add another cell at the end
Cell cell2 = row.createCell((short) 99); Cell cell2 = row.createCell((short) 99);
it = row.cellIterator(); it = row.cellIterator();
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell1 == it.next()); assertTrue(cell1 == it.next());
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell2 == it.next()); assertTrue(cell2 == it.next());
// Add another cell at the beginning // Add another cell at the beginning
Cell cell3 = row.createCell((short) 0); Cell cell3 = row.createCell((short) 0);
it = row.cellIterator(); it = row.cellIterator();
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell3 == it.next()); assertTrue(cell3 == it.next());
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell1 == it.next()); assertTrue(cell1 == it.next());
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell2 == it.next()); assertTrue(cell2 == it.next());
// Replace cell1 // Replace cell1
Cell cell4 = row.createCell((short) 1); Cell cell4 = row.createCell((short) 1);
it = row.cellIterator(); it = row.cellIterator();
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell3 == it.next()); assertTrue(cell3 == it.next());
assertTrue(it.hasNext()); assertTrue(it.hasNext());
@ -68,7 +70,7 @@ public class TestXSSFRow extends TestCase {
assertTrue(it.hasNext()); assertTrue(it.hasNext());
assertTrue(cell2 == it.next()); assertTrue(cell2 == it.next());
assertFalse(it.hasNext()); assertFalse(it.hasNext());
// Add another cell, specifying the cellType // Add another cell, specifying the cellType
Cell cell5 = row.createCell((short) 2, Cell.CELL_TYPE_STRING); Cell cell5 = row.createCell((short) 2, Cell.CELL_TYPE_STRING);
it = row.cellIterator(); it = row.cellIterator();
@ -83,24 +85,26 @@ public class TestXSSFRow extends TestCase {
assertTrue(cell2 == it.next()); assertTrue(cell2 == it.next());
assertEquals(Cell.CELL_TYPE_STRING, cell5.getCellType()); assertEquals(Cell.CELL_TYPE_STRING, cell5.getCellType());
} }
public void testGetCell() throws Exception { public void testGetCell() {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
assertNotNull(row.getCell((short) 2)); assertNotNull(row.getCell((short) 2));
assertNotNull(row.getCell((short) 3)); assertNotNull(row.getCell((short) 3));
assertNotNull(row.getCell((short) 4)); assertNotNull(row.getCell((short) 4));
assertEquals(Cell.CELL_TYPE_NUMERIC, row.getCell((short) 3).getCellType()); // cell3 may have been created as CELL_TYPE_NUMERIC, but since there is no numeric
// value set yet, its cell type is classified as 'blank'
assertEquals(Cell.CELL_TYPE_BLANK, row.getCell((short) 3).getCellType());
assertNull(row.getCell((short) 5)); assertNull(row.getCell((short) 5));
} }
public void testGetPhysicalNumberOfCells() throws Exception { public void testGetPhysicalNumberOfCells() {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
assertEquals(7, row.getPhysicalNumberOfCells()); assertEquals(7, row.getPhysicalNumberOfCells());
} }
public void testGetFirstCellNum() throws Exception { public void testGetFirstCellNum() {
// Test a row with some cells // Test a row with some cells
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
assertFalse(row.getFirstCellNum() == (short) 0); assertFalse(row.getFirstCellNum() == (short) 0);
assertEquals((short) 2, row.getFirstCellNum()); assertEquals((short) 2, row.getFirstCellNum());
@ -109,13 +113,13 @@ public class TestXSSFRow extends TestCase {
Cell cell = row.getCell((short) 2); Cell cell = row.getCell((short) 2);
row.removeCell(cell); row.removeCell(cell);
assertFalse(row.getFirstCellNum() == (short) 2); assertFalse(row.getFirstCellNum() == (short) 2);
// Test a row without cells // Test a row without cells
XSSFRow emptyRow = new XSSFRow(createParentObjects()); XSSFRow emptyRow = new XSSFRow(createParentObjects());
assertEquals(-1, emptyRow.getFirstCellNum()); assertEquals(-1, emptyRow.getFirstCellNum());
} }
public void testLastCellNum() throws Exception { public void testLastCellNum() {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
assertEquals(100, row.getLastCellNum()); assertEquals(100, row.getLastCellNum());
@ -123,26 +127,25 @@ public class TestXSSFRow extends TestCase {
row.removeCell(cell); row.removeCell(cell);
assertFalse(row.getLastCellNum() == (short) 100); assertFalse(row.getLastCellNum() == (short) 100);
} }
public void testRemoveCell() throws Exception {
XSSFRow row = getSampleRow();
// Test removing the first cell public void testRemoveCell() {
Cell firstCell = row.getCell((short) 2); XSSFRow row = getSampleRow();
assertNotNull(firstCell);
assertEquals(7, row.getPhysicalNumberOfCells()); // Test removing the first cell
row.removeCell(firstCell); Cell firstCell = row.getCell((short) 2);
assertEquals(6, row.getPhysicalNumberOfCells()); assertNotNull(firstCell);
firstCell = row.getCell((short) 2); assertEquals(7, row.getPhysicalNumberOfCells());
assertNull(firstCell); row.removeCell(firstCell);
assertEquals(6, row.getPhysicalNumberOfCells());
// Test removing the last cell firstCell = row.getCell((short) 2);
Cell lastCell = row.getCell((short) 100); assertNull(firstCell);
row.removeCell(lastCell);
// Test removing the last cell
Cell lastCell = row.getCell((short) 100);
row.removeCell(lastCell);
} }
public void testGetSetHeight() throws Exception { public void testGetSetHeight() {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
// I assume that "ht" attribute value is in 'points', please verify that // I assume that "ht" attribute value is in 'points', please verify that
// Test that no rowHeight is set // Test that no rowHeight is set
@ -150,37 +153,37 @@ public class TestXSSFRow extends TestCase {
// Set a rowHeight in twips (1/20th of a point) and test the new value // Set a rowHeight in twips (1/20th of a point) and test the new value
row.setHeight((short) 240); row.setHeight((short) 240);
assertEquals((short) 240, row.getHeight()); assertEquals((short) 240, row.getHeight());
assertEquals((float) 12, row.getHeightInPoints()); assertEquals(12F, row.getHeightInPoints());
// Set a new rowHeight in points and test the new value // Set a new rowHeight in points and test the new value
row.setHeightInPoints((float) 13); row.setHeightInPoints(13F);
assertEquals((float) 13, row.getHeightInPoints()); assertEquals((float) 13, row.getHeightInPoints());
assertEquals((short) 260, row.getHeight()); assertEquals((short) 260, row.getHeight());
} }
public void testGetSetZeroHeight() throws Exception { public void testGetSetZeroHeight() throws Exception {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
assertFalse(row.getZeroHeight()); assertFalse(row.getZeroHeight());
row.setZeroHeight(true); row.setZeroHeight(true);
assertTrue(row.getZeroHeight()); assertTrue(row.getZeroHeight());
} }
/** /**
* Method that returns a row with some sample cells * Method that returns a row with some sample cells
* @return row * @return row
*/ */
public XSSFRow getSampleRow() { private static XSSFRow getSampleRow() {
XSSFRow row = new XSSFRow(createParentObjects()); XSSFRow row = new XSSFRow(createParentObjects());
row.createCell((short) 2); row.createCell((short) 2);
row.createCell((short) 3, Cell.CELL_TYPE_NUMERIC); row.createCell((short) 3, Cell.CELL_TYPE_NUMERIC);
row.createCell((short) 4); row.createCell((short) 4);
row.createCell((short) 6); row.createCell((short) 6);
row.createCell((short) 7); row.createCell((short) 7);
row.createCell((short) 8); row.createCell((short) 8);
row.createCell((short) 100); row.createCell((short) 100);
return row; return row;
} }
private XSSFSheet createParentObjects() { private static XSSFSheet createParentObjects() {
XSSFWorkbook wb = new XSSFWorkbook(); XSSFWorkbook wb = new XSSFWorkbook();
wb.setSharedStringSource(new DummySharedStringSource()); wb.setSharedStringSource(new DummySharedStringSource());
return new XSSFSheet(wb); return new XSSFSheet(wb);