3. Moved FormulaError codes out of the Cell interface into enum. Interface isn't a proper place for it 4. Finally finished javadoc on XSSFRow and XSSFCell git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@707445 13f79535-47bb-0310-9956-ffa450edef68pull/6/head
@@ -70,26 +70,6 @@ public interface Cell { | |||
public final static int CELL_TYPE_ERROR = 5; | |||
public final static class CELL_ERROR_TYPE { | |||
private final byte type; | |||
private final String repr; | |||
private CELL_ERROR_TYPE(int type, String repr) { | |||
this.type = (byte)type; | |||
this.repr = repr; | |||
} | |||
public byte getType() { return type; } | |||
public String getStringRepr() { return repr; } | |||
} | |||
public static final CELL_ERROR_TYPE ERROR_NULL = new CELL_ERROR_TYPE(0, "#NULL!"); | |||
public static final CELL_ERROR_TYPE ERROR_DIV0 = new CELL_ERROR_TYPE(7, "#DIV/0!"); | |||
public static final CELL_ERROR_TYPE ERROR_VALUE = new CELL_ERROR_TYPE(15, "#VALUE!"); | |||
public static final CELL_ERROR_TYPE ERROR_REF = new CELL_ERROR_TYPE(23, "#REF!"); | |||
public static final CELL_ERROR_TYPE ERROR_NAME = new CELL_ERROR_TYPE(29, "#NAME?"); | |||
public static final CELL_ERROR_TYPE ERROR_NUM = new CELL_ERROR_TYPE(36, "#NUM!"); | |||
public static final CELL_ERROR_TYPE ERROR_NA = new CELL_ERROR_TYPE(42, "#N/A"); | |||
/** | |||
* set the cell's number within the row (0 based) | |||
* @param num short the cell number | |||
@@ -239,12 +219,12 @@ public interface Cell { | |||
byte getErrorCellValue(); | |||
/** | |||
* set the style for the cell. The style should be an HSSFCellStyle created/retreived from | |||
* the HSSFWorkbook. | |||
* set the style for the cell. The style should be an CellStyle created/retreived from | |||
* the Workbook. | |||
* | |||
* @param style reference contained in the workbook | |||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle() | |||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short) | |||
* @see Workbook#createCellStyle() | |||
* @see Workbook#getCellStyleAt(short) | |||
*/ | |||
void setCellStyle(CellStyle style); | |||
@@ -252,7 +232,7 @@ public interface Cell { | |||
/** | |||
* get the style for the cell. This is a reference to a cell style contained in the workbook | |||
* object. | |||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short) | |||
* @see Workbook#getCellStyleAt(short) | |||
*/ | |||
CellStyle getCellStyle(); | |||
@@ -262,20 +242,6 @@ public interface Cell { | |||
*/ | |||
void setAsActiveCell(); | |||
/** | |||
* Returns a string representation of the cell | |||
* | |||
* This method returns a simple representation, | |||
* anthing more complex should be in user code, with | |||
* knowledge of the semantics of the sheet being processed. | |||
* | |||
* 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> | |||
*/ | |||
String toString(); | |||
/** | |||
* Assign a comment to this cell | |||
* | |||
@@ -295,12 +261,12 @@ public interface Cell { | |||
* | |||
* @return hyperlink associated with this cell or null if not found | |||
*/ | |||
public Hyperlink getHyperlink(); | |||
Hyperlink getHyperlink(); | |||
/** | |||
* Assign a hypelrink to this cell | |||
* | |||
* @param link hypelrink associated with this cell | |||
*/ | |||
public void setHyperlink(Hyperlink link); | |||
void setHyperlink(Hyperlink link); | |||
} |
@@ -0,0 +1,140 @@ | |||
/* ==================================================================== | |||
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.ss.usermodel; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
/** | |||
* Enumerates error values in SpreadsheetML formula calculations. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public enum FormulaError { | |||
/** | |||
* Intended to indicate when two areas are required to intersect, but do not. | |||
* <p>Example: | |||
* In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary | |||
* intersection operator, when a comma was intended. end example] | |||
* </p> | |||
*/ | |||
NULL(0x00, "#NULL!"), | |||
/** | |||
* Intended to indicate when any number, including zero, is divided by zero. | |||
* Note: However, any error code divided by zero results in that error code. | |||
*/ | |||
DIV0(0x07, "#DIV/0!"), | |||
/** | |||
* Intended to indicate when an incompatible type argument is passed to a function, or | |||
* an incompatible type operand is used with an operator. | |||
* <p>Example: | |||
* In the case of a function argument, text was expected, but a number was provided | |||
* </p> | |||
*/ | |||
VALUE(0x0F, "#VALUE!"), | |||
/** | |||
* Intended to indicate when a cell reference is invalid. | |||
* <p>Example: | |||
* If a formula contains a reference to a cell, and then the row or column containing that cell is deleted, | |||
* a #REF! error results. If a worksheet does not support 20,001 columns, | |||
* OFFSET(A1,0,20000) will result in a #REF! error. | |||
* </p> | |||
*/ | |||
REF(0x1D, "#REF!"), | |||
/** | |||
* Intended to indicate when what looks like a name is used, but no such name has been defined. | |||
* <p>Example: | |||
* XYZ/3, where XYZ is not a defined name. Total is & A10, | |||
* where neither Total nor is is a defined name. Presumably, "Total is " & A10 | |||
* was intended. SUM(A1C10), where the range A1:C10 was intended. | |||
* </p> | |||
*/ | |||
NAME(0x1D, "#NAME?"), | |||
/** | |||
* Intended to indicate when an argument to a function has a compatible type, but has a | |||
* value that is outside the domain over which that function is defined. (This is known as | |||
* a domain error.) | |||
* <p>Example: | |||
* Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors. | |||
* </p> | |||
* Intended to indicate that the result of a function cannot be represented in a value of | |||
* the specified type, typically due to extreme magnitude. (This is known as a range | |||
* error.) | |||
* <p>Example: FACT(1000) might result in a range error. </p> | |||
*/ | |||
NUM(0x24, "#NUM!"), | |||
/** | |||
* Intended to indicate when a designated value is not available. | |||
* <p>Example: | |||
* Some functions, such as SUMX2MY2, perform a series of operations on corresponding | |||
* elements in two arrays. If those arrays do not have the same number of elements, then | |||
* for some elements in the longer array, there are no corresponding elements in the | |||
* shorter one; that is, one or more values in the shorter array are not available. | |||
* </p> | |||
* This error value can be produced by calling the function NA | |||
*/ | |||
NA(0x2A, "#N/A"); | |||
private byte type; | |||
private String repr; | |||
private FormulaError(int type, String repr) { | |||
this.type = (byte) type; | |||
this.repr = repr; | |||
} | |||
/** | |||
* @return numeric code of the error | |||
*/ | |||
public int getCode() { | |||
return type; | |||
} | |||
/** | |||
* @return string representation of the error | |||
*/ | |||
public String getString() { | |||
return repr; | |||
} | |||
private static Map<String, FormulaError> smap = new HashMap<String, FormulaError>(); | |||
private static Map<Integer, FormulaError> imap = new HashMap<Integer, FormulaError>(); | |||
static{ | |||
for (FormulaError error : values()) { | |||
imap.put(error.getCode(), error); | |||
smap.put(error.getString(), error); | |||
} | |||
} | |||
public static FormulaError forInt(int type){ | |||
FormulaError err = imap.get(type); | |||
if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); | |||
return err; | |||
} | |||
public static FormulaError forString(String code){ | |||
FormulaError err = smap.get(code); | |||
if(err == null) throw new IllegalArgumentException("Unknown error code: " + code); | |||
return err; | |||
} | |||
} |
@@ -866,6 +866,7 @@ public class XSSFCellStyle implements CellStyle, Cloneable { | |||
* @param fmt the index of a data format | |||
*/ | |||
public void setDataFormat(short fmt) { | |||
cellXf.setApplyNumberFormat(true); | |||
cellXf.setNumFmtId((long)fmt); | |||
} | |||
@@ -17,11 +17,8 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.*; | |||
import org.apache.poi.hssf.usermodel.HSSFCell; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; | |||
@@ -30,28 +27,38 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; | |||
/** | |||
* High level representation of a row of a spreadsheet. | |||
*/ | |||
public class XSSFRow implements Row, Comparable { | |||
public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
private CTRow row; | |||
private List<Cell> cells; | |||
private XSSFSheet sheet; | |||
/** | |||
* the xml bean containing all cell definitions for this row | |||
*/ | |||
private final CTRow row; | |||
/** | |||
* Cells of this row keyed by their column indexes. | |||
* The TreeMap ensures that the cells are ordered by columnIndex in the ascending order. | |||
*/ | |||
private final TreeMap<Integer, Cell> cells; | |||
/** | |||
* Create a new XSSFRow. | |||
* | |||
* @param row The underlying XMLBeans row. | |||
* @param sheet The parent sheet. | |||
* the parent sheet | |||
*/ | |||
public XSSFRow(CTRow row, XSSFSheet sheet) { | |||
private final XSSFSheet sheet; | |||
/** | |||
* Construct a XSSFRow. | |||
* | |||
* @param row the xml bean containing all cell definitions for this row. | |||
* @param sheet the parent sheet. | |||
*/ | |||
protected XSSFRow(CTRow row, XSSFSheet sheet) { | |||
this.row = row; | |||
this.sheet = sheet; | |||
this.cells = new LinkedList<Cell>(); | |||
this.cells = new TreeMap<Integer, Cell>(); | |||
for (CTCell c : row.getCArray()) { | |||
this.cells.add(new XSSFCell(this, c)); | |||
XSSFCell cell = new XSSFCell(this, c); | |||
this.cells.put(cell.getColumnIndex(), cell); | |||
} | |||
} | |||
/** | |||
@@ -62,25 +69,39 @@ public class XSSFRow implements Row, Comparable { | |||
public XSSFSheet getSheet() { | |||
return this.sheet; | |||
} | |||
/** | |||
* @return Cell iterator of the physically defined cells. Note element 4 may | |||
* actually be row cell depending on how many are defined! | |||
* Cell iterator over the physically defined cells: | |||
* <blockquote><pre> | |||
* for (Iterator<Cell> it = row.cellIterator(); it.hasNext(); ) { | |||
* Cell cell = it.next(); | |||
* ... | |||
* } | |||
* </pre></blockquote> | |||
* | |||
* @return an iterator over cells in this row. | |||
*/ | |||
public Iterator<Cell> cellIterator() { | |||
return cells.iterator(); | |||
return cells.values().iterator(); | |||
} | |||
/** | |||
* Alias for {@link #cellIterator()} to allow | |||
* foreach loops | |||
* Alias for {@link #cellIterator()} to allow foreach loops: | |||
* <blockquote><pre> | |||
* for(Cell cell : row){ | |||
* ... | |||
* } | |||
* </pre></blockquote> | |||
* | |||
* @return an iterator over cells in this row. | |||
*/ | |||
public Iterator<Cell> iterator() { | |||
return cellIterator(); | |||
} | |||
/** | |||
* Compares two <code>XSSFRow</code> objects. | |||
* Compares two <code>XSSFRow</code> objects. Two rows are equal if they belong to the same worksheet and | |||
* their row indexes are equal. | |||
* | |||
* @param row the <code>XSSFRow</code> to be compared. | |||
* @return the value <code>0</code> if the row number of this <code>XSSFRow</code> is | |||
@@ -89,84 +110,57 @@ public class XSSFRow implements Row, Comparable { | |||
* than the row number of the argument <code>XSSFRow</code>; and a value greater | |||
* than <code>0</code> if the row number of this this <code>XSSFRow</code> is numerically | |||
* greater than the row number of the argument <code>XSSFRow</code>. | |||
* @throws IllegalArgumentException if the argument row belongs to a different worksheet | |||
*/ | |||
public int compareTo(Object row) { | |||
public int compareTo(XSSFRow row) { | |||
int thisVal = this.getRowNum(); | |||
int anotherVal = ((XSSFRow)row).getRowNum(); | |||
if(row.getSheet() != getSheet()) throw new IllegalArgumentException("The compared rows must belong to the same XSSFSheet"); | |||
int anotherVal = row.getRowNum(); | |||
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); | |||
} | |||
/** | |||
* Use this to create new cells within the row and return it. | |||
* <p> | |||
* The cell that is returned is a CELL_TYPE_BLANK. The type can be changed | |||
* The cell that is returned is a {@link Cell#CELL_TYPE_BLANK}. The type can be changed | |||
* either through calling <code>setCellValue</code> or <code>setCellType</code>. | |||
* | |||
* @param column - the column number this cell represents | |||
* </p> | |||
* @param columnIndex - the column number this cell represents | |||
* @return Cell a high level representation of the created cell. | |||
* @throws IllegalArgumentException if columnIndex < 0 | |||
*/ | |||
public XSSFCell createCell(int column) { | |||
return createCell(column, Cell.CELL_TYPE_BLANK); | |||
} | |||
/** | |||
* Add a new empty cell to this row. | |||
* | |||
* @param column Cell column number. | |||
* @param index Position where to insert cell. | |||
* @param type cell type, one of Cell.CELL_TYPE_* | |||
* @return The new cell. | |||
*/ | |||
protected XSSFCell addCell(int column, int index, int type) { | |||
CTCell ctcell = row.insertNewC(index); | |||
XSSFCell xcell = new XSSFCell(this, ctcell); | |||
xcell.setCellNum(column); | |||
if (type != Cell.CELL_TYPE_BLANK) { | |||
xcell.setCellType(type); | |||
} | |||
return xcell; | |||
public XSSFCell createCell(int columnIndex) { | |||
return createCell(columnIndex, Cell.CELL_TYPE_BLANK); | |||
} | |||
/** | |||
* Use this to create new cells within the row and return it. | |||
* | |||
* @param column - the column number this cell represents | |||
* @param columnIndex - the column number this cell represents | |||
* @param type - the cell's data type | |||
* | |||
* @return XSSFCell a high level representation of the created cell. | |||
* @throws IllegalArgumentException if columnIndex < 0 or if the specified cell type is invalid | |||
* @see Cell#CELL_TYPE_BLANK | |||
* @see Cell#CELL_TYPE_BOOLEAN | |||
* @see Cell#CELL_TYPE_ERROR | |||
* @see Cell#CELL_TYPE_FORMULA | |||
* @see Cell#CELL_TYPE_NUMERIC | |||
* @see Cell#CELL_TYPE_STRING | |||
*/ | |||
public XSSFCell createCell(int column, int type) { | |||
int index = 0; | |||
for (Cell c : this.cells) { | |||
if (c.getColumnIndex() == column) { | |||
// Replace c with new Cell | |||
XSSFCell xcell = addCell(column, index, type); | |||
cells.set(index, xcell); | |||
return xcell; | |||
} | |||
if (c.getColumnIndex() > column) { | |||
XSSFCell xcell = addCell(column, index, type); | |||
cells.add(index, xcell); | |||
return xcell; | |||
} | |||
++index; | |||
public XSSFCell createCell(int columnIndex, int type) { | |||
if(columnIndex < 0) throw new IllegalArgumentException("columnIndex must be >= 0, was " + columnIndex); | |||
CTCell ctcell = CTCell.Factory.newInstance(); | |||
XSSFCell xcell = new XSSFCell(this, ctcell); | |||
xcell.setCellNum(columnIndex); | |||
if (type != Cell.CELL_TYPE_BLANK) { | |||
xcell.setCellType(type); | |||
} | |||
XSSFCell xcell = addCell(column, index, type); | |||
cells.add(xcell); | |||
cells.put(columnIndex, xcell); | |||
return xcell; | |||
} | |||
private XSSFCell retrieveCell(int cellnum) { | |||
Iterator<Cell> it = cellIterator(); | |||
for ( ; it.hasNext() ; ) { | |||
Cell cell = it.next(); | |||
if (cell.getColumnIndex() == cellnum) { | |||
return (XSSFCell)cell; | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Returns the cell at the given (0 based) index, | |||
* with the {@link MissingCellPolicy} from the parent Workbook. | |||
@@ -176,28 +170,33 @@ public class XSSFRow implements Row, Comparable { | |||
public XSSFCell getCell(int cellnum) { | |||
return getCell(cellnum, sheet.getWorkbook().getMissingCellPolicy()); | |||
} | |||
/** | |||
* Returns the cell at the given (0 based) index, | |||
* with the specified {@link MissingCellPolicy} | |||
* Returns the cell at the given (0 based) index, with the specified {@link MissingCellPolicy} | |||
* | |||
* @return the cell at the given (0 based) index | |||
* @throws IllegalArgumentException if cellnum < 0 or the specified MissingCellPolicy is invalid | |||
* @see Row#RETURN_NULL_AND_BLANK | |||
* @see Row#RETURN_BLANK_AS_NULL | |||
* @see Row#CREATE_NULL_AS_BLANK | |||
*/ | |||
public XSSFCell getCell(int cellnum, MissingCellPolicy policy) { | |||
XSSFCell cell = retrieveCell(cellnum); | |||
if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0"); | |||
XSSFCell cell = (XSSFCell)cells.get(cellnum); | |||
if(policy == RETURN_NULL_AND_BLANK) { | |||
return cell; | |||
} | |||
if(policy == RETURN_BLANK_AS_NULL) { | |||
if(cell == null) return cell; | |||
if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) { | |||
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) { | |||
return null; | |||
} | |||
return cell; | |||
} | |||
if(policy == CREATE_NULL_AS_BLANK) { | |||
if(cell == null) { | |||
return createCell((short)cellnum, HSSFCell.CELL_TYPE_BLANK); | |||
return createCell((short)cellnum, Cell.CELL_TYPE_BLANK); | |||
} | |||
return cell; | |||
} | |||
@@ -207,41 +206,11 @@ public class XSSFRow implements Row, Comparable { | |||
/** | |||
* Get the number of the first cell contained in this row. | |||
* | |||
* @return short representing the first logical cell in the row, or -1 if the row does not contain any cells. | |||
* @return short representing the first logical cell in the row, | |||
* or -1 if the row does not contain any cells. | |||
*/ | |||
public short getFirstCellNum() { | |||
for (Iterator<Cell> it = cellIterator() ; it.hasNext() ; ) { | |||
Cell cell = it.next(); | |||
if (cell != null) { | |||
return (short)cell.getColumnIndex(); | |||
} | |||
} | |||
return -1; | |||
} | |||
/** | |||
* Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned, | |||
* See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} | |||
* | |||
* @return row height measured in twips (1/20th of a point) | |||
*/ | |||
public short getHeight() { | |||
return (short)(getHeightInPoints()*20); | |||
} | |||
/** | |||
* Returns row height measured in point size. If the height is not set, the default worksheet value is returned, | |||
* See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} | |||
* | |||
* @return row height measured in point size | |||
* @see org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints() | |||
*/ | |||
public float getHeightInPoints() { | |||
if (this.row.isSetHt()) { | |||
return (float) this.row.getHt(); | |||
} else { | |||
return sheet.getDefaultRowHeightInPoints(); | |||
} | |||
return (short)(cells.size() == 0 ? -1 : cells.firstKey()); | |||
} | |||
/** | |||
@@ -260,70 +229,36 @@ public class XSSFRow implements Row, Comparable { | |||
* } | |||
* </pre> | |||
* | |||
* @return short representing the last logical cell in the row <b>PLUS ONE</b>, or -1 if the | |||
* row does not contain any cells. | |||
* @return short representing the last logical cell in the row <b>PLUS ONE</b>, | |||
* or -1 if the row does not contain any cells. | |||
*/ | |||
public short getLastCellNum() { | |||
short lastCellNum = -1; | |||
for (Iterator<Cell> it = cellIterator() ; it.hasNext() ; ) { | |||
Cell cell = it.next(); | |||
if (cell != null) { | |||
lastCellNum = (short)(cell.getColumnIndex() + 1); | |||
} | |||
} | |||
return lastCellNum; | |||
return (short)(cells.size() == 0 ? -1 : (cells.lastKey() + 1)); | |||
} | |||
/** | |||
* Gets the number of defined cells (NOT number of cells in the actual row!). | |||
* That is to say if only columns 0,4,5 have values then there would be 3. | |||
* | |||
* @return int representing the number of defined cells in the row. | |||
*/ | |||
public int getPhysicalNumberOfCells() { | |||
int count = 0; | |||
for (Iterator<Cell> it = cellIterator() ; it.hasNext() ; ) { | |||
if (it.next() != null) { | |||
count++; | |||
} | |||
} | |||
return count; | |||
} | |||
/** | |||
* Get row number this row represents | |||
* | |||
* @return the row number (0 based) | |||
*/ | |||
public int getRowNum() { | |||
return (int) (row.getR() - 1); | |||
} | |||
/** | |||
* Get whether or not to display this row with 0 height | |||
* Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned, | |||
* See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} | |||
* | |||
* @return - height is zero or not. | |||
* @return row height measured in twips (1/20th of a point) | |||
*/ | |||
public boolean getZeroHeight() { | |||
return this.row.getHidden(); | |||
public short getHeight() { | |||
return (short)(getHeightInPoints()*20); | |||
} | |||
/** | |||
* Remove the Cell from this row. | |||
* Returns row height measured in point size. If the height is not set, the default worksheet value is returned, | |||
* See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} | |||
* | |||
* @param cell to remove | |||
* @return row height measured in point size | |||
* @see org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints() | |||
*/ | |||
public void removeCell(Cell cell) { | |||
int counter = 0; | |||
for (Iterator<Cell> it = cellIterator(); it.hasNext(); ) { | |||
Cell c = it.next(); | |||
if (c.getColumnIndex() == cell.getColumnIndex()) { | |||
it.remove(); | |||
row.removeC(counter); | |||
continue; | |||
} | |||
counter++; | |||
} | |||
public float getHeightInPoints() { | |||
if (this.row.isSetHt()) { | |||
return (float) this.row.getHt(); | |||
} else { | |||
return sheet.getDefaultRowHeightInPoints(); | |||
} | |||
} | |||
/** | |||
@@ -350,14 +285,44 @@ public class XSSFRow implements Row, Comparable { | |||
setHeight((short)(height*20)); | |||
} | |||
/** | |||
* Gets the number of defined cells (NOT number of cells in the actual row!). | |||
* That is to say if only columns 0,4,5 have values then there would be 3. | |||
* | |||
* @return int representing the number of defined cells in the row. | |||
*/ | |||
public int getPhysicalNumberOfCells() { | |||
return cells.size(); | |||
} | |||
/** | |||
* Get row number this row represents | |||
* | |||
* @return the row number (0 based) | |||
*/ | |||
public int getRowNum() { | |||
return (int) (row.getR() - 1); | |||
} | |||
/** | |||
* Set the row number of this row. | |||
* | |||
* @param rowNum the row number (0-based) | |||
* @throws IllegalArgumentException if rowNum < 0 | |||
*/ | |||
public void setRowNum(int rowNum) { | |||
if(rowNum < 0) throw new IllegalArgumentException("Row number must be >= 0"); | |||
this.row.setR(rowNum + 1); | |||
} | |||
/** | |||
* Get whether or not to display this row with 0 height | |||
* | |||
* @return - height is zero or not. | |||
*/ | |||
public boolean getZeroHeight() { | |||
return this.row.getHidden(); | |||
} | |||
/** | |||
@@ -369,14 +334,48 @@ public class XSSFRow implements Row, Comparable { | |||
this.row.setHidden(height); | |||
} | |||
/** | |||
* Remove the Cell from this row. | |||
* | |||
* @param cell the cell to remove | |||
*/ | |||
public void removeCell(Cell cell) { | |||
cells.remove(cell.getColumnIndex()); | |||
} | |||
/** | |||
* Returns the underlying CTRow xml bean representing this row | |||
* Returns the underlying CTRow xml bean containing all cell definitions in this row | |||
* | |||
* @return the underlying CTRow bean | |||
* @return the underlying CTRow xml bean | |||
*/ | |||
public CTRow getCTRow(){ | |||
return this.row; | |||
return row; | |||
} | |||
/** | |||
* Fired when the document is written to an output stream. | |||
* <p> | |||
* Attaches CTCell beans to the underlying CTRow bean | |||
* </p> | |||
* @see org.apache.poi.xssf.usermodel.XSSFSheet#commit() | |||
*/ | |||
protected void onDocumentWrite(){ | |||
ArrayList<CTCell> cArray = new ArrayList<CTCell>(cells.size()); | |||
//create array of CTCell objects. | |||
//TreeMap's value iterator ensures that the cells are ordered by columnIndex in the ascending order | |||
for (Cell cell : cells.values()) { | |||
XSSFCell c = (XSSFCell)cell; | |||
cArray.add(c.getCTCell()); | |||
} | |||
row.setCArray(cArray.toArray(new CTCell[cArray.size()])); | |||
} | |||
/** | |||
* @return formatted xml representation of this row | |||
*/ | |||
@Override | |||
public String toString(){ | |||
return row.toString(); | |||
} | |||
} |
@@ -71,7 +71,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
protected CTSheet sheet; | |||
protected CTWorksheet worksheet; | |||
protected List<Row> rows; | |||
protected TreeMap<Integer, Row> rows; | |||
protected List<XSSFHyperlink> hyperlinks; | |||
protected ColumnHelper columnHelper; | |||
private CommentsSource sheetComments; | |||
@@ -156,9 +156,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
} | |||
protected void initRows(CTWorksheet worksheet) { | |||
this.rows = new LinkedList<Row>(); | |||
this.rows = new TreeMap<Integer, Row>(); | |||
for (CTRow row : worksheet.getSheetData().getRowArray()) { | |||
this.rows.add(new XSSFRow(row, this)); | |||
XSSFRow r = new XSSFRow(row, this); | |||
this.rows.put(r.getRowNum(), r); | |||
} | |||
} | |||
@@ -307,13 +308,6 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
return (XSSFComment)sheetComments.addComment(); | |||
} | |||
protected XSSFRow addRow(int index, int rownum) { | |||
CTRow row = this.worksheet.getSheetData().insertNewRow(index); | |||
XSSFRow xrow = new XSSFRow(row, this); | |||
xrow.setRowNum(rownum); | |||
return xrow; | |||
} | |||
/** | |||
* Create a new row within the sheet and return the high level representation | |||
* | |||
@@ -322,24 +316,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
* @see #removeRow(org.apache.poi.ss.usermodel.Row) | |||
*/ | |||
public XSSFRow createRow(int rownum) { | |||
int index = 0; | |||
for (Row r : this.rows) { | |||
if (r.getRowNum() == rownum) { | |||
// Replace r with new row | |||
XSSFRow xrow = addRow(index, rownum); | |||
rows.set(index, xrow); | |||
return xrow; | |||
} | |||
if (r.getRowNum() > rownum) { | |||
XSSFRow xrow = addRow(index, rownum); | |||
rows.add(index, xrow); | |||
return xrow; | |||
} | |||
++index; | |||
} | |||
XSSFRow xrow = addRow(index, rownum); | |||
rows.add(xrow); | |||
return xrow; | |||
CTRow ctRow = CTRow.Factory.newInstance(); | |||
XSSFRow r = new XSSFRow(ctRow, this); | |||
r.setRowNum(rownum); | |||
rows.put(r.getRowNum(), r); | |||
return r; | |||
} | |||
/** | |||
@@ -737,14 +718,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
* @return <code>XSSFRow</code> representing the rownumber or <code>null</code> if its not defined on the sheet | |||
*/ | |||
public XSSFRow getRow(int rownum) { | |||
//TODO current implemenation is expensive, it should take O(1), not O(N) | |||
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) { | |||
Row row = it.next(); | |||
if (row.getRowNum() == rownum) { | |||
return (XSSFRow)row; | |||
} | |||
} | |||
return null; | |||
return (XSSFRow)rows.get(rownum); | |||
} | |||
/** | |||
@@ -926,7 +900,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
private short getMaxOutlineLevelRows(){ | |||
short outlineLevel=0; | |||
for(Row r:rows){ | |||
for(Row r : rows.values()){ | |||
XSSFRow xrow=(XSSFRow)r; | |||
outlineLevel=xrow.getCTRow().getOutlineLevel()>outlineLevel? xrow.getCTRow().getOutlineLevel(): outlineLevel; | |||
} | |||
@@ -1067,16 +1041,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
} | |||
public void removeRow(Row row) { | |||
int counter = 0; | |||
int rowNum=row.getRowNum(); | |||
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) { | |||
Row r = it.next(); | |||
if (r.getRowNum() == rowNum) { | |||
it.remove(); | |||
worksheet.getSheetData().removeRow(counter); | |||
} | |||
counter++; | |||
} | |||
rows.remove(row.getRowNum()); | |||
} | |||
/** | |||
@@ -1093,7 +1059,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
} | |||
public Iterator<Row> rowIterator() { | |||
return rows.iterator(); | |||
return rows.values().iterator(); | |||
} | |||
/** | |||
@@ -1444,6 +1410,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
row.setRowNum(row.getRowNum() + n); | |||
} | |||
} | |||
//rebuild the rows map | |||
TreeMap<Integer, Row> map = new TreeMap<Integer, Row>(); | |||
for(Row r : this) map.put(r.getRowNum(), r); | |||
rows = map; | |||
} | |||
/** | |||
@@ -1680,6 +1650,15 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
worksheet.getHyperlinks().setHyperlinkArray(ctHls); | |||
} | |||
CTSheetData sheetData = worksheet.getSheetData(); | |||
ArrayList<CTRow> rArray = new ArrayList<CTRow>(rows.size()); | |||
for(Row row : rows.values()){ | |||
XSSFRow r = (XSSFRow)row; | |||
r.onDocumentWrite(); | |||
rArray.add(r.getCTRow()); | |||
} | |||
sheetData.setRowArray(rArray.toArray(new CTRow[rArray.size()])); | |||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); | |||
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet")); | |||
@@ -25,13 +25,7 @@ import junit.framework.TestCase; | |||
import org.apache.poi.hssf.usermodel.HSSFCell; | |||
import org.apache.poi.hssf.usermodel.HSSFRichTextString; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.CreationHelper; | |||
import org.apache.poi.ss.usermodel.DataFormat; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.apache.poi.ss.usermodel.Workbook; | |||
import org.apache.poi.ss.usermodel.*; | |||
import org.apache.poi.xssf.XSSFTestDataSamples; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; | |||
@@ -51,18 +45,39 @@ public final class TestXSSFCell extends TestCase { | |||
public void testSetGetBoolean() throws Exception { | |||
XSSFRow row = createParentObjects(); | |||
XSSFCell cell = row.createCell(0); | |||
//for blank cells getBooleanCellValue returns false | |||
assertFalse(cell.getBooleanCellValue()); | |||
cell.setCellValue(true); | |||
assertEquals(Cell.CELL_TYPE_BOOLEAN, cell.getCellType()); | |||
assertTrue(cell.getBooleanCellValue()); | |||
cell.setCellValue(false); | |||
assertFalse(cell.getBooleanCellValue()); | |||
cell.setCellType(Cell.CELL_TYPE_NUMERIC); | |||
try { | |||
cell.getBooleanCellValue(); | |||
fail("Exception expected"); | |||
} catch (NumberFormatException e) { | |||
} catch (IllegalStateException e) { | |||
// success | |||
assertEquals("Cannot get a boolean value from a numeric cell", e.getMessage()); | |||
} | |||
cell.setCellValue("1"); | |||
assertEquals(Cell.CELL_TYPE_STRING, cell.getCellType()); | |||
try { | |||
cell.getBooleanCellValue(); | |||
fail("Exception expected"); | |||
} catch (IllegalStateException e) { | |||
// success | |||
assertEquals("Cannot get a boolean value from a text cell", e.getMessage()); | |||
} | |||
//reverted to a blank cell | |||
cell.setCellType(Cell.CELL_TYPE_BLANK); | |||
assertFalse(cell.getBooleanCellValue()); | |||
} | |||
/** | |||
@@ -71,15 +86,54 @@ public final class TestXSSFCell extends TestCase { | |||
public void testSetGetNumeric() throws Exception { | |||
XSSFRow row = createParentObjects(); | |||
XSSFCell cell = row.createCell(0); | |||
cell.setCellValue(10d); | |||
assertEquals(0.0, cell.getNumericCellValue()); | |||
cell.setCellValue(10.0); | |||
assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCellType()); | |||
assertEquals(10d, cell.getNumericCellValue()); | |||
assertEquals(10.0, cell.getNumericCellValue()); | |||
cell.setCellValue(-23.76); | |||
assertEquals(-23.76, cell.getNumericCellValue()); | |||
} | |||
cell.setCellValue("string"); | |||
try { | |||
cell.getNumericCellValue(); | |||
fail("Exception expected"); | |||
} catch (IllegalStateException e) { | |||
// success | |||
assertEquals("Cannot get a numeric value from a text cell", e.getMessage()); | |||
} | |||
cell.setCellValue(true); | |||
try { | |||
cell.getNumericCellValue(); | |||
fail("Exception expected"); | |||
} catch (IllegalStateException e) { | |||
// success | |||
assertEquals("Cannot get a numeric value from a boolean cell", e.getMessage()); | |||
} | |||
//reverted to a blank cell | |||
cell.setCellType(Cell.CELL_TYPE_BLANK); | |||
assertEquals(0.0, cell.getNumericCellValue()); | |||
//setting numeric value for a formula cell does not change the cell type | |||
XSSFCell fcell = row.createCell(1); | |||
fcell.setCellFormula("SUM(C4:E4)"); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, fcell.getCellType()); | |||
fcell.setCellValue(36.6); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, fcell.getCellType()); | |||
assertEquals(36.6, fcell.getNumericCellValue()); | |||
//the said above is true for error cells | |||
fcell.setCellType(Cell.CELL_TYPE_ERROR); | |||
assertEquals(36.6, fcell.getNumericCellValue()); | |||
fcell.setCellValue(16.6); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, fcell.getCellType()); | |||
assertEquals(16.6, fcell.getNumericCellValue()); | |||
} | |||
/** | |||
* Test setting and getting numeric values. | |||
* Test setting and getting date values. | |||
*/ | |||
public void testSetGetDate() throws Exception { | |||
XSSFRow row = createParentObjects(); | |||
@@ -100,8 +154,9 @@ public final class TestXSSFCell extends TestCase { | |||
try { | |||
cell.getDateCellValue(); | |||
fail("Exception expected"); | |||
} catch (NumberFormatException e) { | |||
} catch (IllegalStateException e) { | |||
// success | |||
assertEquals("Cannot get a numeric value from a boolean cell", e.getMessage()); | |||
} | |||
cell.setCellValue(cal); | |||
@@ -109,6 +164,34 @@ public final class TestXSSFCell extends TestCase { | |||
} | |||
/** | |||
* Test setting and getting date values. | |||
*/ | |||
public void testSetGetType() throws Exception { | |||
XSSFRow row = createParentObjects(); | |||
XSSFCell cell = row.createCell(0); | |||
cell.setCellType(Cell.CELL_TYPE_BLANK); | |||
assertEquals(Cell.CELL_TYPE_BLANK, cell.getCellType()); | |||
cell.setCellType(Cell.CELL_TYPE_STRING); | |||
assertEquals(Cell.CELL_TYPE_STRING, cell.getCellType()); | |||
cell.setCellType(Cell.CELL_TYPE_FORMULA); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType()); | |||
cell.setCellFormula(null); | |||
//number cell w/o value is treated as a Blank cell | |||
cell.setCellType(Cell.CELL_TYPE_NUMERIC); | |||
assertFalse(cell.getCTCell().isSetV()); | |||
assertEquals(Cell.CELL_TYPE_BLANK, cell.getCellType()); | |||
//normal number cells have set values | |||
cell.setCellType(Cell.CELL_TYPE_NUMERIC); | |||
cell.getCTCell().setV("0"); | |||
assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCellType()); | |||
cell.setCellType(Cell.CELL_TYPE_BOOLEAN); | |||
assertEquals(Cell.CELL_TYPE_BOOLEAN, cell.getCellType()); | |||
} | |||
public void testSetGetError() throws Exception { | |||
XSSFRow row = createParentObjects(); | |||
XSSFCell cell = row.createCell(0); | |||
@@ -116,14 +199,15 @@ public final class TestXSSFCell extends TestCase { | |||
cell.setCellErrorValue((byte)0); | |||
assertEquals(Cell.CELL_TYPE_ERROR, cell.getCellType()); | |||
assertEquals((byte)0, cell.getErrorCellValue()); | |||
//YK setting numeric value of a error cell does not change the cell type | |||
cell.setCellValue(2.2); | |||
assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCellType()); | |||
assertEquals(Cell.CELL_TYPE_ERROR, cell.getCellType()); | |||
cell.setCellErrorValue(Cell.ERROR_NAME); | |||
cell.setCellErrorValue(FormulaError.NAME); | |||
assertEquals(Cell.CELL_TYPE_ERROR, cell.getCellType()); | |||
assertEquals(Cell.ERROR_NAME.getType(), cell.getErrorCellValue()); | |||
assertEquals(Cell.ERROR_NAME.getStringRepr(), cell.getErrorCellString()); | |||
assertEquals(FormulaError.NAME.getCode(), cell.getErrorCellValue()); | |||
assertEquals(FormulaError.NAME.getString(), cell.getErrorCellString()); | |||
} | |||
public void testSetGetFormula() throws Exception { | |||
@@ -135,7 +219,13 @@ public final class TestXSSFCell extends TestCase { | |||
assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType()); | |||
assertEquals(formula, cell.getCellFormula()); | |||
assertTrue( Double.isNaN( cell.getNumericCellValue() )); | |||
assertEquals(0.0, cell.getNumericCellValue()); | |||
cell.setCellValue(44.5); //set precalculated value | |||
assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType()); | |||
assertEquals(44.5, cell.getNumericCellValue()); | |||
cell.setCellValue(""); //set precalculated value | |||
} | |||
public void testSetGetStringInline() throws Exception { | |||
@@ -166,14 +256,27 @@ public final class TestXSSFCell extends TestCase { | |||
public void testSetGetStringShared() { | |||
XSSFRow row = createParentObjects(); | |||
XSSFCell cell = row.createCell(0); | |||
//we return empty string for blank cells | |||
assertEquals("", cell.getStringCellValue()); | |||
cell.setCellValue(new XSSFRichTextString("")); | |||
cell.setCellValue(new XSSFRichTextString("test")); | |||
assertEquals(Cell.CELL_TYPE_STRING, cell.getCellType()); | |||
assertEquals("", cell.getRichStringCellValue().getString()); | |||
assertEquals("test", cell.getRichStringCellValue().getString()); | |||
cell.setCellValue(new XSSFRichTextString("Foo")); | |||
assertEquals(Cell.CELL_TYPE_STRING, cell.getCellType()); | |||
assertEquals("Foo", cell.getRichStringCellValue().getString()); | |||
cell.setCellValue((String)null); | |||
assertEquals(Cell.CELL_TYPE_BLANK, cell.getCellType()); | |||
XSSFCell fcell = row.createCell(1); | |||
fcell.setCellFormula("SUM(C4:E4)"); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, fcell.getCellType()); | |||
fcell.setCellValue("36.6"); | |||
assertEquals(Cell.CELL_TYPE_FORMULA, fcell.getCellType()); | |||
assertEquals("36.6", fcell.getStringCellValue()); | |||
} | |||
/** | |||
@@ -185,7 +288,7 @@ public final class TestXSSFCell extends TestCase { | |||
cell.setCellType(Cell.CELL_TYPE_BOOLEAN); | |||
assertFalse(cell.getBooleanCellValue()); | |||
cell.setCellType(Cell.CELL_TYPE_NUMERIC); | |||
assertTrue(Double.isNaN( cell.getNumericCellValue() )); | |||
assertEquals(0.0, cell.getNumericCellValue() ); | |||
assertNull(cell.getDateCellValue()); | |||
cell.setCellType(Cell.CELL_TYPE_ERROR); | |||
assertEquals(0, cell.getErrorCellValue()); | |||
@@ -246,17 +349,15 @@ public final class TestXSSFCell extends TestCase { | |||
XSSFComment comment = sheet.createComment(); | |||
comment.setAuthor(TEST_C10_AUTHOR); | |||
CTWorksheet ctWorksheet = sheet.getWorksheet(); | |||
// Create C10 cell | |||
Row row = sheet.createRow(9); | |||
Cell cell = row.createCell(2); | |||
XSSFRow row = sheet.createRow(9); | |||
XSSFCell cell = row.createCell(2); | |||
row.createCell(3); | |||
// Set a comment for C10 cell | |||
cell.setCellComment(comment); | |||
CTCell ctCell = ctWorksheet.getSheetData().getRowArray(0).getCArray(0); | |||
CTCell ctCell = cell.getCTCell(); | |||
assertNotNull(ctCell); | |||
assertEquals("C10", ctCell.getR()); | |||
assertEquals(TEST_C10_AUTHOR, comment.getAuthor()); | |||
@@ -407,7 +508,7 @@ public final class TestXSSFCell extends TestCase { | |||
assertEquals(hcell.toString(),xcell.toString()); | |||
//ERROR | |||
xcell.setCellErrorValue(Cell.ERROR_VALUE); | |||
xcell.setCellErrorValue(FormulaError.VALUE); | |||
xcell.setCellType(Cell.CELL_TYPE_ERROR); | |||
hcell.setCellErrorValue((byte)0); |
@@ -42,12 +42,12 @@ public final class TestXSSFFormulaEvaluation extends TestCase { | |||
Cell c1 = r.createCell(0); | |||
c1.setCellFormula("1+5"); | |||
assertTrue( Double.isNaN(c1.getNumericCellValue()) ); | |||
assertEquals(0.0, c1.getNumericCellValue() ); | |||
Cell c2 = r.createCell(1); | |||
c2.setCellFormula("10/2"); | |||
assertTrue( Double.isNaN(c2.getNumericCellValue()) ); | |||
assertEquals(0.0, c2.getNumericCellValue() ); | |||
FormulaEvaluator fe = new XSSFFormulaEvaluator(wb); | |||
fe.evaluateFormulaCell(c1); | |||
@@ -70,19 +70,19 @@ public final class TestXSSFFormulaEvaluation extends TestCase { | |||
Cell c1 = r.createCell(0); | |||
c1.setCellFormula("SUM(A1:B1)"); | |||
assertTrue( Double.isNaN(c1.getNumericCellValue()) ); | |||
assertEquals(0.0, c1.getNumericCellValue() ); | |||
Cell c2 = r.createCell(1); | |||
c2.setCellFormula("SUM(A1:E1)"); | |||
assertTrue( Double.isNaN(c2.getNumericCellValue()) ); | |||
assertEquals(0.0, c2.getNumericCellValue() ); | |||
Cell c3 = r.createCell(2); | |||
c3.setCellFormula("COUNT(A1:A1)"); | |||
assertTrue( Double.isNaN(c3.getNumericCellValue()) ); | |||
assertEquals(0.0, c3.getNumericCellValue() ); | |||
Cell c4 = r.createCell(3); | |||
c4.setCellFormula("COUNTA(A1:E1)"); | |||
assertTrue( Double.isNaN(c4.getNumericCellValue()) ); | |||
assertEquals(0.0, c4.getNumericCellValue() ); | |||
// Evaluate and test |
@@ -793,9 +793,7 @@ public class TestXSSFSheet extends TestCase { | |||
//one level | |||
sheet.groupRow(9,10); | |||
assertEquals(2,sheet.rows.size()); | |||
CTRow[]rowArray=sheet.getWorksheet().getSheetData().getRowArray(); | |||
assertEquals(2,rowArray.length); | |||
CTRow ctrow=rowArray[0]; | |||
CTRow ctrow = sheet.getRow(8).getCTRow(); | |||
assertNotNull(ctrow); | |||
assertEquals(9,ctrow.getR()); | |||
@@ -804,10 +802,8 @@ public class TestXSSFSheet extends TestCase { | |||
//two level | |||
sheet.groupRow(10,13); | |||
rowArray=sheet.getWorksheet().getSheetData().getRowArray(); | |||
assertEquals(5,rowArray.length); | |||
assertEquals(5,sheet.rows.size()); | |||
ctrow=rowArray[1]; | |||
ctrow = sheet.getRow(9).getCTRow(); | |||
assertNotNull(ctrow); | |||
assertEquals(10,ctrow.getR()); | |||
assertEquals(2, ctrow.getOutlineLevel()); | |||
@@ -815,14 +811,11 @@ public class TestXSSFSheet extends TestCase { | |||
sheet.ungroupRow(8, 10); | |||
rowArray=sheet.getWorksheet().getSheetData().getRowArray(); | |||
assertEquals(4,rowArray.length); | |||
assertEquals(4,sheet.rows.size()); | |||
assertEquals(1,sheet.getSheetTypeSheetFormatPr().getOutlineLevelRow()); | |||
sheet.ungroupRow(10,10); | |||
rowArray=sheet.getWorksheet().getSheetData().getRowArray(); | |||
assertEquals(3,rowArray.length); | |||
assertEquals(3,sheet.rows.size()); | |||
assertEquals(3,sheet.rows.size()); | |||
assertEquals(1,sheet.getSheetTypeSheetFormatPr().getOutlineLevelRow()); | |||
} |