You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/09/13 15:48:31 UTC
svn commit: r694947 [4/6] - in /poi/branches/ooxml: ./
src/documentation/content/xdocs/ src/java/org/apache/poi/hssf/extractor/
src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/
src/java/org/apache/poi/hssf/record/aggregates/ src...
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java Sat Sep 13 06:48:27 2008
@@ -23,6 +23,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.model.Sheet;
@@ -60,8 +61,8 @@
* Cells can be numeric, formula-based or string-based (text). The cell type
* specifies this. String cells cannot conatin numbers and numeric cells cannot
* contain strings (at least according to our model). Client apps should do the
- * conversions themselves. Formula cells have the formula string, as well as
- * the formula result, which can be numeric or string.
+ * conversions themselves. Formula cells have the formula string, as well as
+ * the formula result, which can be numeric or string.
* <p>
* Cells should have their number (0 based) before being added to a row. Only
* cells that have values should be added.
@@ -86,14 +87,15 @@
public final static int CELL_TYPE_BOOLEAN = 4;
/** Error Cell type (5) @see #setCellType(int) @see #getCellType() */
public final static int CELL_TYPE_ERROR = 5;
-
+
public final static short ENCODING_UNCHANGED = -1;
public final static short ENCODING_COMPRESSED_UNICODE = 0;
public final static short ENCODING_UTF_16 = 1;
+
+ private final HSSFWorkbook book;
+ private final HSSFSheet sheet;
private int cellType;
private HSSFRichTextString stringValue;
- private HSSFWorkbook book;
- private Sheet sheet;
private CellValueRecordInterface record;
private HSSFComment comment;
@@ -113,7 +115,7 @@
*
* @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
*/
- protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col)
+ protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, int row, short col)
{
checkBounds(col);
stringValue = null;
@@ -123,9 +125,12 @@
// Relying on the fact that by default the cellType is set to 0 which
// is different to CELL_TYPE_BLANK hence the following method call correctly
// creates a new blank cell.
- short xfindex = sheet.getXFIndexForColAt(col);
+ short xfindex = sheet.getSheet().getXFIndexForColAt(col);
setCellType(CELL_TYPE_BLANK, false, row, col,xfindex);
}
+ public HSSFSheet getSheet() {
+ return sheet;
+ }
/**
* Creates new Cell - Should only be called by HSSFRow. This creates a cell
@@ -140,7 +145,7 @@
* Type of cell
* @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
*/
- protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col,
+ protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, int row, short col,
int type)
{
checkBounds(col);
@@ -148,8 +153,8 @@
stringValue = null;
this.book = book;
this.sheet = sheet;
-
- short xfindex = sheet.getXFIndexForColAt(col);
+
+ short xfindex = sheet.getSheet().getXFIndexForColAt(col);
setCellType(type,false,row,col,xfindex);
}
@@ -161,7 +166,7 @@
* @param sheet - Sheet record of the sheet containing this cell
* @param cval - the Cell Value Record we wish to represent
*/
- protected HSSFCell(HSSFWorkbook book, Sheet sheet, CellValueRecordInterface cval) {
+ protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, CellValueRecordInterface cval) {
record = cval;
cellType = determineType(cval);
stringValue = null;
@@ -190,10 +195,10 @@
* used internally -- given a cell value record, figure out its type
*/
private static int determineType(CellValueRecordInterface cval) {
- if (cval instanceof FormulaRecordAggregate) {
- return HSSFCell.CELL_TYPE_FORMULA;
- }
- // all others are plain BIFF records
+ if (cval instanceof FormulaRecordAggregate) {
+ return HSSFCell.CELL_TYPE_FORMULA;
+ }
+ // all others are plain BIFF records
Record record = ( Record ) cval;
switch (record.getSid()) {
@@ -209,13 +214,13 @@
}
throw new RuntimeException("Bad cell value rec (" + cval.getClass().getName() + ")");
}
-
+
/**
* Returns the Workbook that this Cell is bound to
* @return
*/
protected Workbook getBoundWorkbook() {
- return book.getWorkbook();
+ return book.getWorkbook();
}
/**
@@ -233,7 +238,7 @@
{
record.setColumn(num);
}
-
+
/**
* Updates the cell record's idea of what
* column it belongs in (0 based)
@@ -241,7 +246,7 @@
*/
protected void updateCellNum(short num)
{
- record.setColumn(num);
+ record.setColumn(num);
}
/**
@@ -295,7 +300,7 @@
FormulaRecordAggregate frec;
if (cellType != this.cellType) {
- frec = sheet.createFormula(row, col);
+ frec = sheet.getSheet().createFormula(row, col);
} else {
frec = (FormulaRecordAggregate) record;
frec.setRow(row);
@@ -421,17 +426,17 @@
errRec.setColumn(col);
if (setValue)
{
- errRec.setValue(getErrorCellValue());
+ errRec.setValue((byte)HSSFErrorConstants.ERROR_VALUE);
}
errRec.setXFIndex(styleIndex);
errRec.setRow(row);
record = errRec;
break;
}
- if (cellType != this.cellType &&
+ if (cellType != this.cellType &&
this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell
{
- sheet.replaceValueRecord(record);
+ sheet.getSheet().replaceValueRecord(record);
}
this.cellType = cellType;
}
@@ -457,21 +462,20 @@
* precalculated value, for numerics we'll set its value. For other types we
* will change the cell to a numeric cell and set its value.
*/
- public void setCellValue(double value)
- {
+ public void setCellValue(double value) {
int row=record.getRow();
short col=record.getColumn();
short styleIndex=record.getXFIndex();
- if ((cellType != CELL_TYPE_NUMERIC) && (cellType != CELL_TYPE_FORMULA))
- {
- setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
- }
-
- // Save into the appropriate record
- if(record instanceof FormulaRecordAggregate) {
- (( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
- } else {
- (( NumberRecord ) record).setValue(value);
+
+ switch (cellType) {
+ default:
+ setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
+ case CELL_TYPE_ERROR:
+ (( NumberRecord ) record).setValue(value);
+ break;
+ case CELL_TYPE_FORMULA:
+ ((FormulaRecordAggregate)record).getFormulaRecord().setValue(value);
+ break;
}
}
@@ -491,7 +495,7 @@
/**
* set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
* a date.
- *
+ *
* This will set the cell value based on the Calendar's timezone. As Excel
* does not support timezones this means that both 20:00+03:00 and
* 20:00-03:00 will be reported as the same value (20:00) even that there
@@ -547,31 +551,20 @@
return;
}
if (cellType == CELL_TYPE_FORMULA) {
- // Set the 'pre-evaluated result' for the formula
+ // Set the 'pre-evaluated result' for the formula
// note - formulas do not preserve text formatting.
FormulaRecordAggregate fr = (FormulaRecordAggregate) record;
-
- // Save the string into a String Record, creating
- // one if required
- StringRecord sr = fr.getStringRecord();
- if(sr == null) {
- // Wasn't a string before, need a new one
- sr = new StringRecord();
- fr.setStringRecord(sr);
- }
-
- // Save, loosing the formatting
- sr.setString(hvalue.getString());
+ fr.setCachedStringResult(hvalue.getString());
// Update our local cache to the un-formatted version
- stringValue = new HSSFRichTextString(sr.getString());
-
+ stringValue = new HSSFRichTextString(value.getString());
+
// All done
return;
}
// If we get here, we're not dealing with a formula,
// so handle things as a normal rich text cell
-
+
if (cellType != CELL_TYPE_STRING) {
setCellType(CELL_TYPE_STRING, false, row, col, styleIndex);
}
@@ -599,95 +592,95 @@
FormulaRecord frec = rec.getFormulaRecord();
frec.setOptions((short) 2);
frec.setValue(0);
-
+
//only set to default if there is no extended format index already set
if (rec.getXFIndex() == (short)0) {
- rec.setXFIndex((short) 0x0f);
- }
+ rec.setXFIndex((short) 0x0f);
+ }
Ptg[] ptgs = FormulaParser.parse(formula, book);
frec.setParsedExpression(ptgs);
}
+ /* package */ void setFormulaOnly(Ptg[] ptgs) {
+ if (ptgs == null) {
+ throw new IllegalArgumentException("ptgs must not be null");
+ }
+ ((FormulaRecordAggregate)record).getFormulaRecord().setParsedExpression(ptgs);
+ }
public String getCellFormula() {
return FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
}
+ /**
+ * Used to help format error messages
+ */
+ private static String getCellTypeName(int cellTypeCode) {
+ switch (cellTypeCode) {
+ case CELL_TYPE_BLANK: return "blank";
+ case CELL_TYPE_STRING: return "text";
+ case CELL_TYPE_BOOLEAN: return "boolean";
+ case CELL_TYPE_ERROR: return "error";
+ case CELL_TYPE_NUMERIC: return "numeric";
+ case CELL_TYPE_FORMULA: return "formula";
+ }
+ return "#unknown cell type (" + cellTypeCode + ")#";
+ }
+
+ private static RuntimeException typeMismatch(int expectedTypeCode, int actualTypeCode, boolean isFormulaCell) {
+ String msg = "Cannot get a "
+ + getCellTypeName(expectedTypeCode) + " value from a "
+ + getCellTypeName(actualTypeCode) + " " + (isFormulaCell ? "formula " : "") + "cell";
+ return new IllegalStateException(msg);
+ }
+ private static void checkFormulaCachedValueType(int expectedTypeCode, FormulaRecord fr) {
+ int cachedValueType = fr.getCachedResultType();
+ if (cachedValueType != expectedTypeCode) {
+ throw typeMismatch(expectedTypeCode, cachedValueType, true);
+ }
+ }
/**
- * Get the value of the cell as a number.
+ * Get the value of the cell as a number.
* For strings we throw an exception.
* For blank cells we return a 0.
* See {@link HSSFDataFormatter} for turning this
* number into a string similar to that which
- * Excel would render this number as.
+ * Excel would render this number as.
*/
- public double getNumericCellValue()
- {
- if (cellType == CELL_TYPE_BLANK)
- {
- return 0;
- }
- if (cellType == CELL_TYPE_STRING)
- {
- throw new NumberFormatException(
- "You cannot get a numeric value from a String based cell");
- }
- if (cellType == CELL_TYPE_BOOLEAN)
- {
- throw new NumberFormatException(
- "You cannot get a numeric value from a boolean cell");
- }
- if (cellType == CELL_TYPE_ERROR)
- {
- throw new NumberFormatException(
- "You cannot get a numeric value from an error cell");
- }
- if(cellType == CELL_TYPE_NUMERIC)
- {
- return ((NumberRecord)record).getValue();
- }
- if(cellType == CELL_TYPE_FORMULA)
- {
- return ((FormulaRecordAggregate)record).getFormulaRecord().getValue();
+ public double getNumericCellValue() {
+
+ switch(cellType) {
+ case CELL_TYPE_BLANK:
+ return 0.0;
+ case CELL_TYPE_NUMERIC:
+ return ((NumberRecord)record).getValue();
+ default:
+ throw typeMismatch(CELL_TYPE_NUMERIC, cellType, false);
+ case CELL_TYPE_FORMULA:
+ break;
}
- throw new NumberFormatException("Unknown Record Type in Cell:"+cellType);
+ FormulaRecord fr = ((FormulaRecordAggregate)record).getFormulaRecord();
+ checkFormulaCachedValueType(CELL_TYPE_NUMERIC, fr);
+ return fr.getValue();
}
/**
- * Get the value of the cell as a date.
+ * Get the value of the cell as a date.
* For strings we throw an exception.
* For blank cells we return a null.
* See {@link HSSFDataFormatter} for formatting
* this date into a string similar to how excel does.
*/
- public Date getDateCellValue()
- {
- if (cellType == CELL_TYPE_BLANK)
- {
+ public Date getDateCellValue() {
+
+ if (cellType == CELL_TYPE_BLANK) {
return null;
}
- if (cellType == CELL_TYPE_STRING)
- {
- throw new NumberFormatException(
- "You cannot get a date value from a String based cell");
- }
- if (cellType == CELL_TYPE_BOOLEAN)
- {
- throw new NumberFormatException(
- "You cannot get a date value from a boolean cell");
- }
- if (cellType == CELL_TYPE_ERROR)
- {
- throw new NumberFormatException(
- "You cannot get a date value from an error cell");
- }
- double value=this.getNumericCellValue();
+ double value = getNumericCellValue();
if (book.getWorkbook().isUsing1904DateWindowing()) {
- return HSSFDateUtil.getJavaDate(value,true);
- }
- else {
- return HSSFDateUtil.getJavaDate(value,false);
+ return HSSFDateUtil.getJavaDate(value, true);
}
+ return HSSFDateUtil.getJavaDate(value, false);
}
/**
@@ -708,33 +701,22 @@
* For blank cells we return an empty string.
* For formulaCells that are not string Formulas, we return empty String
*/
+ public HSSFRichTextString getRichStringCellValue() {
- public HSSFRichTextString getRichStringCellValue()
- {
- if (cellType == CELL_TYPE_BLANK)
- {
- return new HSSFRichTextString("");
- }
- if (cellType == CELL_TYPE_NUMERIC)
- {
- throw new NumberFormatException(
- "You cannot get a string value from a numeric cell");
- }
- if (cellType == CELL_TYPE_BOOLEAN)
- {
- throw new NumberFormatException(
- "You cannot get a string value from a boolean cell");
- }
- if (cellType == CELL_TYPE_ERROR)
- {
- throw new NumberFormatException(
- "You cannot get a string value from an error cell");
- }
- if (cellType == CELL_TYPE_FORMULA)
- {
- if (stringValue==null) return new HSSFRichTextString("");
+ switch(cellType) {
+ case CELL_TYPE_BLANK:
+ return new HSSFRichTextString("");
+ case CELL_TYPE_STRING:
+ return stringValue;
+ default:
+ throw typeMismatch(CELL_TYPE_STRING, cellType, false);
+ case CELL_TYPE_FORMULA:
+ break;
}
- return stringValue;
+ FormulaRecordAggregate fra = ((FormulaRecordAggregate)record);
+ checkFormulaCachedValueType(CELL_TYPE_STRING, fra.getFormulaRecord());
+ String strVal = fra.getStringValue();
+ return new HSSFRichTextString(strVal == null ? "" : strVal);
}
/**
@@ -745,47 +727,56 @@
* will change the cell to a boolean cell and set its value.
*/
- public void setCellValue(boolean value)
- {
+ public void setCellValue(boolean value) {
int row=record.getRow();
short col=record.getColumn();
short styleIndex=record.getXFIndex();
- if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
- {
- setCellType(CELL_TYPE_BOOLEAN, false, row, col, styleIndex);
+
+ switch (cellType) {
+ default:
+ setCellType(CELL_TYPE_BOOLEAN, false, row, col, styleIndex);
+ case CELL_TYPE_ERROR:
+ (( BoolErrRecord ) record).setValue(value);
+ break;
+ case CELL_TYPE_FORMULA:
+ ((FormulaRecordAggregate)record).getFormulaRecord().setCachedResultBoolean(value);
+ break;
}
- (( BoolErrRecord ) record).setValue(value);
}
/**
* set a error value for the cell
*
- * @param value the error value to set this cell to. For formulas we'll set the
- * precalculated value ??? IS THIS RIGHT??? , for errors we'll set
+ * @param errorCode the error value to set this cell to. For formulas we'll set the
+ * precalculated value , for errors we'll set
* its value. For other types we will change the cell to an error
* cell and set its value.
*/
-
- public void setCellErrorValue(byte value)
- {
+ public void setCellErrorValue(byte errorCode) {
int row=record.getRow();
short col=record.getColumn();
short styleIndex=record.getXFIndex();
- if (cellType != CELL_TYPE_ERROR) {
- setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex);
+ switch (cellType) {
+ default:
+ setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex);
+ case CELL_TYPE_ERROR:
+ (( BoolErrRecord ) record).setValue(errorCode);
+ break;
+ case CELL_TYPE_FORMULA:
+ ((FormulaRecordAggregate)record).getFormulaRecord().setCachedResultErrorCode(errorCode);
+ break;
}
- (( BoolErrRecord ) record).setValue(value);
}
/**
* Chooses a new boolean value for the cell when its type is changing.<p/>
- *
- * Usually the caller is calling setCellType() with the intention of calling
+ *
+ * Usually the caller is calling setCellType() with the intention of calling
* setCellValue(boolean) straight afterwards. This method only exists to give
* the cell a somewhat reasonable value until the setCellValue() call (if at all).
* TODO - perhaps a method like setCellTypeAndValue(int, Object) should be introduced to avoid this
*/
private boolean convertCellValueToBoolean() {
-
+
switch (cellType) {
case CELL_TYPE_BOOLEAN:
return (( BoolErrRecord ) record).getBooleanValue();
@@ -796,11 +787,11 @@
// All other cases convert to false
// These choices are not well justified.
- case CELL_TYPE_FORMULA:
+ case CELL_TYPE_FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
case CELL_TYPE_ERROR:
case CELL_TYPE_BLANK:
- return false;
+ return false;
}
throw new RuntimeException("Unexpected cell type (" + cellType + ")");
}
@@ -809,38 +800,39 @@
* get the value of the cell as a boolean. For strings, numbers, and errors, we throw an exception.
* For blank cells we return a false.
*/
+ public boolean getBooleanCellValue() {
- public boolean getBooleanCellValue()
- {
- if (cellType == CELL_TYPE_BOOLEAN)
- {
- return (( BoolErrRecord ) record).getBooleanValue();
- }
- if (cellType == CELL_TYPE_BLANK)
- {
- return false;
+ switch(cellType) {
+ case CELL_TYPE_BLANK:
+ return false;
+ case CELL_TYPE_BOOLEAN:
+ return (( BoolErrRecord ) record).getBooleanValue();
+ default:
+ throw typeMismatch(CELL_TYPE_BOOLEAN, cellType, false);
+ case CELL_TYPE_FORMULA:
+ break;
}
- throw new NumberFormatException(
- "You cannot get a boolean value from a non-boolean cell");
+ FormulaRecord fr = ((FormulaRecordAggregate)record).getFormulaRecord();
+ checkFormulaCachedValueType(CELL_TYPE_BOOLEAN, fr);
+ return fr.getCachedBooleanValue();
}
/**
* get the value of the cell as an error code. For strings, numbers, and booleans, we throw an exception.
* For blank cells we return a 0.
*/
-
- public byte getErrorCellValue()
- {
- if (cellType == CELL_TYPE_ERROR)
- {
- return (( BoolErrRecord ) record).getErrorValue();
- }
- if (cellType == CELL_TYPE_BLANK)
- {
- return ( byte ) 0;
+ public byte getErrorCellValue() {
+ switch(cellType) {
+ case CELL_TYPE_ERROR:
+ return (( BoolErrRecord ) record).getErrorValue();
+ default:
+ throw typeMismatch(CELL_TYPE_ERROR, cellType, false);
+ case CELL_TYPE_FORMULA:
+ break;
}
- throw new NumberFormatException(
- "You cannot get an error value from a non-error cell");
+ FormulaRecord fr = ((FormulaRecordAggregate)record).getFormulaRecord();
+ checkFormulaCachedValueType(CELL_TYPE_ERROR, fr);
+ return (byte) fr.getCachedErrorValue();
}
/**
@@ -897,7 +889,7 @@
throw new RuntimeException("You cannot reference columns with an index of less then 0.");
}
}
-
+
/**
* Sets this cell as the active cell for the worksheet
*/
@@ -905,45 +897,45 @@
{
int row=record.getRow();
short col=record.getColumn();
- this.sheet.setActiveCellRow(row);
- this.sheet.setActiveCellCol(col);
+ this.sheet.getSheet().setActiveCellRow(row);
+ this.sheet.getSheet().setActiveCellCol(col);
}
-
+
/**
* Returns a string representation of the cell
- *
- * This method returns a simple representation,
+ *
+ * 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.
+ * 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>
*/
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((( BoolErrRecord ) record).getErrorValue());
- case CELL_TYPE_FORMULA:
- return getCellFormula();
- case CELL_TYPE_NUMERIC:
- //TODO apply the dataformat for this cell
- if (HSSFDateUtil.isCellDateFormatted(this)) {
- DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
- return sdf.format(getDateCellValue());
- } else {
- return getNumericCellValue() + "";
- }
- case CELL_TYPE_STRING:
- return getStringCellValue();
- default:
- return "Unknown Cell Type: " + getCellType();
- }
+ switch (getCellType()) {
+ case CELL_TYPE_BLANK:
+ return "";
+ case CELL_TYPE_BOOLEAN:
+ return getBooleanCellValue()?"TRUE":"FALSE";
+ case CELL_TYPE_ERROR:
+ return ErrorEval.getText((( BoolErrRecord ) record).getErrorValue());
+ case CELL_TYPE_FORMULA:
+ return getCellFormula();
+ case CELL_TYPE_NUMERIC:
+ //TODO apply the dataformat for this cell
+ if (HSSFDateUtil.isCellDateFormatted(this)) {
+ DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
+ return sdf.format(getDateCellValue());
+ } else {
+ return getNumericCellValue() + "";
+ }
+ case CELL_TYPE_STRING:
+ return getStringCellValue();
+ default:
+ return "Unknown Cell Type: " + getCellType();
+ }
}
/**
@@ -954,14 +946,14 @@
* @param comment comment associated with this cell
*/
public void setCellComment(Comment comment){
- if(comment == null) {
- removeCellComment();
- return;
- }
-
- this.comment = (HSSFComment) comment;
- this.comment.setRow((short)record.getRow());
- this.comment.setColumn(record.getColumn());
+ if(comment == null) {
+ removeCellComment();
+ return;
+ }
+
+ comment.setRow((short)record.getRow());
+ comment.setColumn(record.getColumn());
+ this.comment = (HSSFComment)comment;
}
/**
@@ -971,11 +963,11 @@
*/
public HSSFComment getCellComment(){
if (comment == null) {
- comment = findCellComment(sheet, record.getRow(), record.getColumn());
+ comment = findCellComment(sheet.getSheet(), record.getRow(), record.getColumn());
}
return comment;
}
-
+
/**
* Removes the comment for this cell, if
* there is one.
@@ -983,40 +975,41 @@
* all comments after performing this action!
*/
public void removeCellComment() {
- HSSFComment comment = findCellComment(sheet, record.getRow(), record.getColumn());
- this.comment = null;
-
- if(comment == null) {
- // Nothing to do
- return;
- }
-
- // Zap the underlying NoteRecord
- sheet.getRecords().remove(comment.getNoteRecord());
-
- // If we have a TextObjectRecord, is should
- // be proceeed by:
- // MSODRAWING with container
- // OBJ
- // MSODRAWING with EscherTextboxRecord
- if(comment.getTextObjectRecord() != null) {
- TextObjectRecord txo = comment.getTextObjectRecord();
- int txoAt = sheet.getRecords().indexOf(txo);
-
- if(sheet.getRecords().get(txoAt-3) instanceof DrawingRecord &&
- sheet.getRecords().get(txoAt-2) instanceof ObjRecord &&
- sheet.getRecords().get(txoAt-1) instanceof DrawingRecord) {
- // Zap these, in reverse order
- sheet.getRecords().remove(txoAt-1);
- sheet.getRecords().remove(txoAt-2);
- sheet.getRecords().remove(txoAt-3);
- } else {
- throw new IllegalStateException("Found the wrong records before the TextObjectRecord, can't remove comment");
- }
-
- // Now remove the text record
- sheet.getRecords().remove(txo);
- }
+ HSSFComment comment = findCellComment(sheet.getSheet(), record.getRow(), record.getColumn());
+ this.comment = null;
+
+ if(comment == null) {
+ // Nothing to do
+ return;
+ }
+
+ // Zap the underlying NoteRecord
+ List sheetRecords = sheet.getSheet().getRecords();
+ sheetRecords.remove(comment.getNoteRecord());
+
+ // If we have a TextObjectRecord, is should
+ // be proceeed by:
+ // MSODRAWING with container
+ // OBJ
+ // MSODRAWING with EscherTextboxRecord
+ if(comment.getTextObjectRecord() != null) {
+ TextObjectRecord txo = comment.getTextObjectRecord();
+ int txoAt = sheetRecords.indexOf(txo);
+
+ if(sheetRecords.get(txoAt-3) instanceof DrawingRecord &&
+ sheetRecords.get(txoAt-2) instanceof ObjRecord &&
+ sheetRecords.get(txoAt-1) instanceof DrawingRecord) {
+ // Zap these, in reverse order
+ sheetRecords.remove(txoAt-1);
+ sheetRecords.remove(txoAt-2);
+ sheetRecords.remove(txoAt-3);
+ } else {
+ throw new IllegalStateException("Found the wrong records before the TextObjectRecord, can't remove comment");
+ }
+
+ // Now remove the text record
+ sheetRecords.remove(txo);
+ }
}
/**
@@ -1070,7 +1063,7 @@
* @return hyperlink associated with this cell or null if not found
*/
public HSSFHyperlink getHyperlink(){
- for (Iterator it = sheet.getRecords().iterator(); it.hasNext(); ) {
+ for (Iterator it = sheet.getSheet().getRecords().iterator(); it.hasNext(); ) {
RecordBase rec = (RecordBase) it.next();
if (rec instanceof HyperlinkRecord){
HyperlinkRecord link = (HyperlinkRecord)rec;
@@ -1108,7 +1101,19 @@
break;
}
- int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
- sheet.getRecords().add( eofLoc, link.record );
+ int eofLoc = sheet.getSheet().findFirstRecordLocBySid( EOFRecord.sid );
+ sheet.getSheet().getRecords().add( eofLoc, link.record );
+ }
+ /**
+ * Only valid for formula cells
+ * @return one of ({@link #CELL_TYPE_NUMERIC}, {@link #CELL_TYPE_STRING},
+ * {@link #CELL_TYPE_BOOLEAN}, {@link #CELL_TYPE_ERROR}) depending
+ * on the cached value of the formula
+ */
+ public int getCachedFormulaResultType() {
+ if (this.cellType != CELL_TYPE_FORMULA) {
+ throw new IllegalStateException("Only formula cells have cached results");
+ }
+ return ((FormulaRecordAggregate)record).getFormulaRecord().getCachedResultType();
}
}
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFDataValidation.java
('svn:mergeinfo' removed)
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Sat Sep 13 06:48:27 2008
@@ -31,6 +31,9 @@
public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
super(sheet, workbook);
}
+ public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
+ super(workbook);
+ }
/**
* Returns an underlying FormulaParser, for the specified
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java Sat Sep 13 06:48:27 2008
@@ -20,7 +20,6 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
-import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.ss.usermodel.Cell;
@@ -55,7 +54,7 @@
/**
* reference to containing Sheet
*/
- private Sheet sheet;
+ private HSSFSheet sheet;
/**
* Creates new HSSFRow from scratch. Only HSSFSheet should do this.
@@ -65,7 +64,7 @@
* @param rowNum the row number of this row (0 based)
* @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int)
*/
- HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum)
+ HSSFRow(HSSFWorkbook book, HSSFSheet sheet, int rowNum)
{
this.rowNum = rowNum;
this.book = book;
@@ -84,7 +83,7 @@
* @param record the low level api object this row should represent
* @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int)
*/
- HSSFRow(HSSFWorkbook book, Sheet sheet, RowRecord record)
+ HSSFRow(HSSFWorkbook book, HSSFSheet sheet, RowRecord record)
{
this.book = book;
this.sheet = sheet;
@@ -139,7 +138,7 @@
HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), shortCellNum, type);
addCell(cell);
- sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
+ sheet.getSheet().addValueRecord(getRowNum(), cell.getCellValueRecord());
return cell;
}
@@ -166,7 +165,7 @@
if(alsoRemoveRecords) {
CellValueRecordInterface cval = cell.getCellValueRecord();
- sheet.removeValueRecord(getRowNum(), cval);
+ sheet.getSheet().removeValueRecord(getRowNum(), cval);
}
if (cell.getCellNum()+1 == row.getLastCol()) {
@@ -465,7 +464,7 @@
//The low-order 15 bits contain the row height.
//The 0x8000 bit indicates that the row is standard height (optional)
- if ((height & 0x8000) != 0) height = sheet.getDefaultRowHeight();
+ if ((height & 0x8000) != 0) height = sheet.getSheet().getDefaultRowHeight();
else height &= 0x7FFF;
return height;
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Sat Sep 13 06:48:27 2008
@@ -207,7 +207,7 @@
*/
public HSSFRow createRow(int rownum)
{
- HSSFRow row = new HSSFRow(workbook, sheet, rownum);
+ HSSFRow row = new HSSFRow(workbook, this, rownum);
addRow(row, true);
return row;
@@ -222,7 +222,7 @@
private HSSFRow createRowFromRecord(RowRecord row)
{
- HSSFRow hrow = new HSSFRow(workbook, sheet, row);
+ HSSFRow hrow = new HSSFRow(workbook, this, row);
addRow(hrow, false);
return hrow;
@@ -390,7 +390,7 @@
for(int index=0; index<records.size(); index++) {
if(records.get(index) instanceof DVRecord) {
- dvRecords.add(records.get(index));
+ dvRecords.add(records.get(index));
}
}
return dvRecords;
@@ -1301,9 +1301,7 @@
// If any references were changed, then
// re-create the formula string
if(changed) {
- c.setCellFormula(
- FormulaParser.toFormulaString(workbook, ptgs)
- );
+ c.setFormulaOnly(ptgs);
}
}
}
@@ -1602,14 +1600,32 @@
}
/**
+ * @deprecated (Sep 2008) use {@link #setColumnGroupCollapsed(int, boolean)}
+ */
+ public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) {
+ setColumnGroupCollapsed(columnNumber & 0xFFFF, collapsed);
+ }
+ /**
+ * @deprecated (Sep 2008) use {@link #groupColumn(int, int)}
+ */
+ public void groupColumn(short fromColumn, short toColumn) {
+ groupColumn(fromColumn & 0xFFFF, toColumn & 0xFFFF);
+ }
+ /**
+ * @deprecated (Sep 2008) use {@link #ungroupColumn(int, int)}
+ */
+ public void ungroupColumn(short fromColumn, short toColumn) {
+ ungroupColumn(fromColumn & 0xFFFF, toColumn & 0xFFFF);
+ }
+
+ /**
* Expands or collapses a column group.
*
* @param columnNumber One of the columns in the group.
* @param collapsed true = collapse group, false = expand group.
*/
- public void setColumnGroupCollapsed( short columnNumber, boolean collapsed )
- {
- sheet.setColumnGroupCollapsed( columnNumber, collapsed );
+ public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) {
+ sheet.setColumnGroupCollapsed(columnNumber, collapsed);
}
/**
@@ -1618,14 +1634,12 @@
* @param fromColumn beginning of the column range.
* @param toColumn end of the column range.
*/
- public void groupColumn(short fromColumn, short toColumn)
- {
- sheet.groupColumnRange( fromColumn, toColumn, true );
+ public void groupColumn(int fromColumn, int toColumn) {
+ sheet.groupColumnRange(fromColumn, toColumn, true);
}
- public void ungroupColumn( short fromColumn, short toColumn )
- {
- sheet.groupColumnRange( fromColumn, toColumn, false );
+ public void ungroupColumn(int fromColumn, int toColumn) {
+ sheet.groupColumnRange(fromColumn, toColumn, false);
}
public void groupRow(int fromRow, int toRow)
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Sat Sep 13 06:48:27 2008
@@ -661,6 +661,16 @@
return -1;
}
+ /* package */ int findSheetIndex(Sheet sheet) {
+ for(int i=0; i<_sheets.size(); i++) {
+ HSSFSheet hSheet = (HSSFSheet) _sheets.get(i);
+ if(hSheet.getSheet() == sheet) {
+ return i;
+ }
+ }
+ throw new IllegalArgumentException("Specified sheet not found in this workbook");
+ }
+
/**
* Returns the external sheet index of the sheet
* with the given internal index, creating one
Copied: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java (from r694881, poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java?p2=poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java&p1=poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java&r1=694881&r2=694947&rev=694947&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java Sat Sep 13 06:48:27 2008
@@ -16,64 +16,14 @@
==================================================================== */
package org.apache.poi.hssf.usermodel;
-
import org.apache.poi.hssf.record.formula.AreaI;
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.AreaEvalBase;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.util.CellReference;
/**
*
* @author Josh Micich
*/
-final class LazyAreaEval extends AreaEvalBase {
-
- private final HSSFSheet _sheet;
- private HSSFFormulaEvaluator _evaluator;
-
+final class LazyAreaEval extends org.apache.poi.ss.usermodel.LazyAreaEval {
public LazyAreaEval(AreaI ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {
- super(ptg);
- _sheet = sheet;
- _evaluator = evaluator;
- }
-
- public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
-
- int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
- int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
-
- HSSFRow row = _sheet.getRow(rowIx);
- if (row == null) {
- return BlankEval.INSTANCE;
- }
- HSSFCell cell = row.getCell(colIx);
- if (cell == null) {
- return BlankEval.INSTANCE;
- }
- return _evaluator.getEvalForCell(cell);
- }
-
- public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
- AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-
- return new LazyAreaEval(area, _sheet, _evaluator);
- }
- public String toString() {
- CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
- CellReference crB = new CellReference(getLastRow(), getLastColumn());
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()).append("[");
- String sheetName = _evaluator.getSheetName(_sheet);
- sb.append(sheetName);
- sb.append('!');
- sb.append(crA.formatAsString());
- sb.append(':');
- sb.append(crB.formatAsString());
- sb.append("]");
- return sb.toString();
+ super(ptg, sheet, evaluator);
}
}
Copied: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java (from r694881, poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java)
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java?p2=poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java&p1=poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java&r1=694881&r2=694947&rev=694947&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java Sat Sep 13 06:48:27 2008
@@ -16,70 +16,18 @@
==================================================================== */
package org.apache.poi.hssf.usermodel;
-
-import org.apache.poi.hssf.record.formula.AreaI;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.util.CellReference;
/**
*
* @author Josh Micich
*/
-final class LazyRefEval extends RefEvalBase {
-
- private final HSSFSheet _sheet;
- private final HSSFFormulaEvaluator _evaluator;
-
-
+final class LazyRefEval extends org.apache.poi.ss.usermodel.LazyRefEval {
public LazyRefEval(RefPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {
- super(ptg.getRow(), ptg.getColumn());
- _sheet = sheet;
- _evaluator = evaluator;
+ super(ptg, sheet, evaluator);
}
public LazyRefEval(Ref3DPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {
- super(ptg.getRow(), ptg.getColumn());
- _sheet = sheet;
- _evaluator = evaluator;
- }
-
- public ValueEval getInnerValueEval() {
- int rowIx = getRow();
- int colIx = getColumn();
-
- HSSFRow row = _sheet.getRow(rowIx);
- if (row == null) {
- return BlankEval.INSTANCE;
- }
- HSSFCell cell = row.getCell(colIx);
- if (cell == null) {
- return BlankEval.INSTANCE;
- }
- return _evaluator.getEvalForCell(cell);
- }
-
- public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
-
- AreaI area = new OffsetArea(getRow(), getColumn(),
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-
- return new LazyAreaEval(area, _sheet, _evaluator);
- }
-
- public String toString() {
- CellReference cr = new CellReference(getRow(), getColumn());
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()).append("[");
- String sheetName = _evaluator.getSheetName(_sheet);
- sb.append(sheetName);
- sb.append('!');
- sb.append(cr.formatAsString());
- sb.append("]");
- return sb.toString();
+ super(ptg, sheet, evaluator);
}
}
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java
('svn:mergeinfo' removed)
Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/EvaluationCycleDetector.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/EvaluationCycleDetector.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/EvaluationCycleDetector.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/EvaluationCycleDetector.java Sat Sep 13 06:48:27 2008
@@ -20,12 +20,9 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
-
/**
* Instances of this class keep track of multiple dependent cell evaluations due
- * to recursive calls to <tt>HSSFFormulaEvaluator.internalEvaluate()</tt>.
+ * to recursive calls to <tt>FormulaEvaluator.internalEvaluate()</tt>.
* The main purpose of this class is to detect an attempt to evaluate a cell
* that is already being evaluated. In other words, it detects circular
* references in spreadsheet formulas.
@@ -40,19 +37,19 @@
private static final class CellEvaluationFrame {
private final Workbook _workbook;
- private final Sheet _sheet;
+ private final int _sheetIndex;
private final int _srcRowNum;
private final int _srcColNum;
- public CellEvaluationFrame(Workbook workbook, Sheet sheet, int srcRowNum, int srcColNum) {
+ public CellEvaluationFrame(Workbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
if (workbook == null) {
throw new IllegalArgumentException("workbook must not be null");
}
- if (sheet == null) {
- throw new IllegalArgumentException("sheet must not be null");
+ if (sheetIndex < 0) {
+ throw new IllegalArgumentException("sheetIndex must not be negative");
}
_workbook = workbook;
- _sheet = sheet;
+ _sheetIndex = sheetIndex;
_srcRowNum = srcRowNum;
_srcColNum = srcColNum;
}
@@ -62,7 +59,7 @@
if (_workbook != other._workbook) {
return false;
}
- if (_sheet != other._sheet) {
+ if (_sheetIndex != other._sheetIndex) {
return false;
}
if (_srcRowNum != other._srcRowNum) {
@@ -78,7 +75,7 @@
* @return human readable string for debug purposes
*/
public String formatAsString() {
- return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _workbook.getSheetIndex(_sheet);
+ return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _sheetIndex;
}
public String toString() {
@@ -111,8 +108,8 @@
* @return <code>true</code> if the specified cell has not been visited yet in the current
* evaluation. <code>false</code> if the specified cell is already being evaluated.
*/
- public boolean startEvaluate(Workbook workbook, Sheet sheet, int srcRowNum, int srcColNum) {
- CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum);
+ public boolean startEvaluate(Workbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
+ CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum);
if (_evaluationFrames.contains(cef)) {
return false;
}
@@ -132,7 +129,7 @@
* required. However, they have been included to assert correct behaviour,
* and form more meaningful error messages.
*/
- public void endEvaluate(Workbook workbook, Sheet sheet, int srcRowNum, int srcColNum) {
+ public void endEvaluate(Workbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
int nFrames = _evaluationFrames.size();
if (nFrames < 1) {
throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate");
@@ -140,7 +137,7 @@
nFrames--;
CellEvaluationFrame cefExpected = (CellEvaluationFrame) _evaluationFrames.get(nFrames);
- CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum);
+ CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum);
if (!cefActual.equals(cefExpected)) {
throw new RuntimeException("Wrong cell specified. "
+ "Corresponding startEvaluate() call was for cell {"
Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java Sat Sep 13 06:48:27 2008
@@ -20,9 +20,6 @@
import java.util.Iterator;
import java.util.Stack;
-import org.apache.poi.ss.util.AreaReference;
-import org.apache.poi.ss.util.CellReference;
-
import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.formula.Area3DPtg;
@@ -49,8 +46,6 @@
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.FunctionEval;
-import org.apache.poi.hssf.record.formula.eval.LazyAreaEval;
-import org.apache.poi.hssf.record.formula.eval.LazyRefEval;
import org.apache.poi.hssf.record.formula.eval.NameEval;
import org.apache.poi.hssf.record.formula.eval.NameXEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
@@ -58,6 +53,7 @@
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.util.CellReference;
/**
* Evaluates formula cells.<p/>
@@ -70,29 +66,37 @@
* @author Josh Micich
*/
public class FormulaEvaluator {
- /**
- * used to track the number of evaluations
- */
+
+ /**
+ * used to track the number of evaluations
+ */
private static final class Counter {
public int value;
+ public int depth;
public Counter() {
value = 0;
}
}
- protected Sheet _sheet;
- protected Workbook _workbook;
+ protected final Workbook _workbook;
private final EvaluationCache _cache;
private Counter _evaluationCounter;
-
+ /**
+ * @deprecated (Sep 2008) Sheet parameter is ignored
+ */
public FormulaEvaluator(Sheet sheet, Workbook workbook) {
- this(sheet, workbook, new EvaluationCache(), new Counter());
+ this(workbook);
+ if (false) {
+ sheet.toString(); // suppress unused parameter compiler warning
+ }
+ }
+ public FormulaEvaluator(Workbook workbook) {
+ this(workbook, new EvaluationCache(), new Counter());
}
-
- private FormulaEvaluator(Sheet sheet, Workbook workbook, EvaluationCache cache, Counter evaluationCounter) {
- _sheet = sheet;
+
+ private FormulaEvaluator(Workbook workbook, EvaluationCache cache, Counter evaluationCounter) {
_workbook = workbook;
_cache = cache;
_evaluationCounter = evaluationCounter;
@@ -140,7 +144,6 @@
_cache.clear();
}
-
/**
* If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from
@@ -150,34 +153,23 @@
* @param cell
*/
public CellValue evaluate(Cell cell) {
- CellValue retval = null;
- if (cell != null) {
- switch (cell.getCellType()) {
- case Cell.CELL_TYPE_BLANK:
- retval = new CellValue(Cell.CELL_TYPE_BLANK, _workbook.getCreationHelper());
- break;
+ if (cell == null) {
+ return null;
+ }
+
+ switch (cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
- retval = new CellValue(Cell.CELL_TYPE_BOOLEAN, _workbook.getCreationHelper());
- retval.setBooleanValue(cell.getBooleanCellValue());
- break;
+ return CellValue.valueOf(cell.getBooleanCellValue());
case Cell.CELL_TYPE_ERROR:
- retval = new CellValue(Cell.CELL_TYPE_ERROR, _workbook.getCreationHelper());
- retval.setErrorValue(cell.getErrorCellValue());
- break;
+ return CellValue.getError(cell.getErrorCellValue());
case Cell.CELL_TYPE_FORMULA:
- retval = getCellValueForEval(internalEvaluate(cell, _sheet), _workbook.getCreationHelper());
- break;
+ return evaluateFormulaCellValue(cell);
case Cell.CELL_TYPE_NUMERIC:
- retval = new CellValue(Cell.CELL_TYPE_NUMERIC, _workbook.getCreationHelper());
- retval.setNumberValue(cell.getNumericCellValue());
- break;
+ return new CellValue(cell.getNumericCellValue(), _workbook.getCreationHelper());
case Cell.CELL_TYPE_STRING:
- retval = new CellValue(Cell.CELL_TYPE_STRING, _workbook.getCreationHelper());
- retval.setRichTextStringValue(cell.getRichStringCellValue());
- break;
- }
+ return new CellValue(cell.getRichStringCellValue().getString(), _workbook.getCreationHelper());
}
- return retval;
+ throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}
@@ -200,32 +192,13 @@
* @return The type of the formula result (the cell's type remains as Cell.CELL_TYPE_FORMULA however)
*/
public int evaluateFormulaCell(Cell cell) {
- if (cell != null) {
- switch (cell.getCellType()) {
- case Cell.CELL_TYPE_FORMULA:
- CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet), _workbook.getCreationHelper());
- switch (cv.getCellType()) {
- case Cell.CELL_TYPE_BOOLEAN:
- cell.setCellValue(cv.getBooleanValue());
- break;
- case Cell.CELL_TYPE_ERROR:
- cell.setCellValue(cv.getErrorValue());
- break;
- case Cell.CELL_TYPE_NUMERIC:
- cell.setCellValue(cv.getNumberValue());
- break;
- case Cell.CELL_TYPE_STRING:
- cell.setCellValue(cv.getRichTextStringValue());
- break;
- case Cell.CELL_TYPE_BLANK:
- break;
- case Cell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
- break;
- }
- return cv.getCellType();
- }
+ if (cell == null || cell.getCellType() != Cell.CELL_TYPE_FORMULA) {
+ return -1;
}
- return -1;
+ CellValue cv = evaluateFormulaCellValue(cell);
+ // cell remains a formula cell, but the cached value is changed
+ setCellValue(cell, cv);
+ return cv.getCellType();
}
/**
@@ -245,35 +218,56 @@
* @param cell
*/
public Cell evaluateInCell(Cell cell) {
- if (cell != null) {
- switch (cell.getCellType()) {
- case Cell.CELL_TYPE_FORMULA:
- CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet), _workbook.getCreationHelper());
- switch (cv.getCellType()) {
- case Cell.CELL_TYPE_BOOLEAN:
- cell.setCellType(Cell.CELL_TYPE_BOOLEAN);
- cell.setCellValue(cv.getBooleanValue());
- break;
- case Cell.CELL_TYPE_ERROR:
- cell.setCellErrorValue(cv.getErrorValue());
- break;
- case Cell.CELL_TYPE_NUMERIC:
- cell.setCellType(Cell.CELL_TYPE_NUMERIC);
- cell.setCellValue(cv.getNumberValue());
- break;
- case Cell.CELL_TYPE_STRING:
- cell.setCellType(Cell.CELL_TYPE_STRING);
- cell.setCellValue(cv.getRichTextStringValue());
- break;
- case Cell.CELL_TYPE_BLANK:
- break;
- case Cell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
- break;
- }
- }
+ if (cell == null) {
+ return null;
+ }
+ if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
+ CellValue cv = evaluateFormulaCellValue(cell);
+ setCellType(cell, cv); // cell will no longer be a formula cell
+ setCellValue(cell, cv);
}
return cell;
}
+ private static void setCellType(Cell cell, CellValue cv) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case Cell.CELL_TYPE_BOOLEAN:
+ case Cell.CELL_TYPE_ERROR:
+ case Cell.CELL_TYPE_NUMERIC:
+ case Cell.CELL_TYPE_STRING:
+ cell.setCellType(cellType);
+ return;
+ case Cell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case Cell.CELL_TYPE_FORMULA:
+ // this will never happen, we have already evaluated the formula
+ }
+ throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+ }
+
+ private static void setCellValue(Cell cell, CellValue cv) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case Cell.CELL_TYPE_BOOLEAN:
+ cell.setCellValue(cv.getBooleanValue());
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ cell.setCellErrorValue(cv.getErrorValue());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ cell.setCellValue(cv.getNumberValue());
+ break;
+ case Cell.CELL_TYPE_STRING:
+ cell.setCellValue(cv.getRichTextStringValue());
+ break;
+ case Cell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case Cell.CELL_TYPE_FORMULA:
+ // this will never happen, we have already evaluated the formula
+ default:
+ throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+ }
+ }
/**
* Loops over all cells in all sheets of the supplied
@@ -287,9 +281,9 @@
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(Workbook wb) {
+ FormulaEvaluator evaluator = new FormulaEvaluator(wb);
for(int i=0; i<wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
- FormulaEvaluator evaluator = new FormulaEvaluator(sheet, wb);
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
Row r = (Row)rit.next();
@@ -303,72 +297,61 @@
}
}
-
/**
* Returns a CellValue wrapper around the supplied ValueEval instance.
* @param eval
*/
- private static CellValue getCellValueForEval(ValueEval eval, CreationHelper cHelper) {
- CellValue retval = null;
- if (eval != null) {
- if (eval instanceof NumberEval) {
- NumberEval ne = (NumberEval) eval;
- retval = new CellValue(Cell.CELL_TYPE_NUMERIC, cHelper);
- retval.setNumberValue(ne.getNumberValue());
- }
- else if (eval instanceof BoolEval) {
- BoolEval be = (BoolEval) eval;
- retval = new CellValue(Cell.CELL_TYPE_BOOLEAN, cHelper);
- retval.setBooleanValue(be.getBooleanValue());
- }
- else if (eval instanceof StringEval) {
- StringEval ne = (StringEval) eval;
- retval = new CellValue(Cell.CELL_TYPE_STRING, cHelper);
- retval.setStringValue(ne.getStringValue());
- }
- else if (eval instanceof BlankEval) {
- retval = new CellValue(Cell.CELL_TYPE_BLANK, cHelper);
- }
- else if (eval instanceof ErrorEval) {
- retval = new CellValue(Cell.CELL_TYPE_ERROR, cHelper);
- retval.setErrorValue((byte)((ErrorEval)eval).getErrorCode());
-// retval.setRichTextStringValue(new RichTextString("#An error occurred. check cell.getErrorCode()"));
- }
- else {
- retval = new CellValue(Cell.CELL_TYPE_ERROR, cHelper);
- }
+ private CellValue evaluateFormulaCellValue(Cell cell) {
+ ValueEval eval = internalEvaluate(cell);
+ if (eval instanceof NumberEval) {
+ NumberEval ne = (NumberEval) eval;
+ return new CellValue(ne.getNumberValue(), _workbook.getCreationHelper());
+ }
+ if (eval instanceof BoolEval) {
+ BoolEval be = (BoolEval) eval;
+ return CellValue.valueOf(be.getBooleanValue());
+ }
+ if (eval instanceof StringEval) {
+ StringEval ne = (StringEval) eval;
+ return new CellValue(ne.getStringValue(), _workbook.getCreationHelper());
+ }
+ if (eval instanceof ErrorEval) {
+ return CellValue.getError(((ErrorEval)eval).getErrorCode());
}
- return retval;
+ throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
/**
* Dev. Note: Internal evaluate must be passed only a formula cell
* else a runtime exception will be thrown somewhere inside the method.
* (Hence this is a private method.)
+ * @return never <code>null</code>, never {@link BlankEval}
*/
- private ValueEval internalEvaluate(Cell srcCell, Sheet sheet) {
+ private ValueEval internalEvaluate(Cell srcCell) {
int srcRowNum = srcCell.getRowIndex();
int srcColNum = srcCell.getCellNum();
ValueEval result;
- int sheetIndex = _workbook.getSheetIndex(sheet);
+ int sheetIndex = _workbook.getSheetIndex(srcCell.getSheet());
result = _cache.getValue(sheetIndex, srcRowNum, srcColNum);
if (result != null) {
- return result;
+ return result;
}
_evaluationCounter.value++;
+ _evaluationCounter.depth++;
EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker();
- if(!tracker.startEvaluate(_workbook, sheet, srcRowNum, srcColNum)) {
+ if(!tracker.startEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum)) {
return ErrorEval.CIRCULAR_REF_ERROR;
}
try {
- result = evaluateCell(srcRowNum, (short)srcColNum, srcCell.getCellFormula());
+ result = evaluateCell(sheetIndex, srcRowNum, (short)srcColNum, srcCell.getCellFormula());
} finally {
- tracker.endEvaluate(_workbook, sheet, srcRowNum, srcColNum);
+ tracker.endEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum);
_cache.setValue(sheetIndex, srcRowNum, srcColNum, result);
+ _evaluationCounter.depth--;
}
if (isDebugLogEnabled()) {
String sheetName = _workbook.getSheetName(sheetIndex);
@@ -377,7 +360,7 @@
}
return result;
}
- private ValueEval evaluateCell(int srcRowNum, short srcColNum, String cellFormulaText) {
+ private ValueEval evaluateCell(int sheetIndex, int srcRowNum, short srcColNum, String cellFormulaText) {
Ptg[] ptgs = FormulaParser.parse(cellFormulaText, _workbook);
@@ -392,8 +375,8 @@
}
if (ptg instanceof MemErrPtg) { continue; }
if (ptg instanceof MissingArgPtg) {
- // TODO - might need to push BlankEval or MissingArgEval
- continue;
+ // TODO - might need to push BlankEval or MissingArgEval
+ continue;
}
Eval opResult;
if (ptg instanceof OperationPtg) {
@@ -411,15 +394,15 @@
Eval p = (Eval) stack.pop();
ops[j] = p;
}
- logDebug("invoke " + operation + " (nAgs=" + numops + ")");
- opResult = invokeOperation(operation, ops, srcRowNum, srcColNum, _workbook, _sheet);
+// logDebug("invoke " + operation + " (nAgs=" + numops + ")");
+ opResult = invokeOperation(operation, ops, _workbook, sheetIndex, srcRowNum, srcColNum);
} else {
- opResult = getEvalForPtg(ptg, _sheet);
+ opResult = getEvalForPtg(ptg, sheetIndex);
}
if (opResult == null) {
throw new RuntimeException("Evaluation result must not be null");
}
- logDebug("push " + opResult);
+// logDebug("push " + opResult);
stack.push(opResult);
}
@@ -428,7 +411,7 @@
throw new IllegalStateException("evaluation stack not empty");
}
value = dereferenceValue(value, srcRowNum, srcColNum);
- if (value instanceof BlankEval) {
+ if (value == BlankEval.INSTANCE) {
// Note Excel behaviour here. A blank final final value is converted to zero.
return NumberEval.ZERO;
// Formulas _never_ evaluate to blank. If a formula appears to have evaluated to
@@ -464,24 +447,21 @@
return evaluationResult;
}
- private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum,
- Workbook workbook, Sheet sheet) {
+ private static Eval invokeOperation(OperationEval operation, Eval[] ops,
+ Workbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
if(operation instanceof FunctionEval) {
FunctionEval fe = (FunctionEval) operation;
if(fe.isFreeRefFunction()) {
- return fe.getFreeRefFunction().evaluate(ops, srcRowNum, srcColNum, workbook, sheet);
+ return fe.getFreeRefFunction().evaluate(ops, workbook, sheetIndex, srcRowNum, srcColNum);
}
}
- return operation.evaluate(ops, srcRowNum, srcColNum);
+ return operation.evaluate(ops, srcRowNum, (short)srcColNum);
}
private Sheet getOtherSheet(int externSheetIndex) {
return _workbook.getSheetAt(_workbook.getSheetIndexFromExternSheetIndex(externSheetIndex));
}
- private FormulaEvaluator createEvaluatorForAnotherSheet(Sheet sheet) {
- return new FormulaEvaluator(sheet, _workbook, _cache, _evaluationCounter);
- }
/**
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
@@ -489,7 +469,7 @@
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
* passed here!
*/
- private Eval getEvalForPtg(Ptg ptg, Sheet sheet) {
+ private Eval getEvalForPtg(Ptg ptg, int sheetIndex) {
if (ptg instanceof NamePtg) {
// named ranges, macro functions
NamePtg namePtg = (NamePtg) ptg;
@@ -499,41 +479,23 @@
throw new RuntimeException("Bad name index (" + nameIndex
+ "). Allowed range is (0.." + (numberOfNames-1) + ")");
}
- if(_workbook instanceof org.apache.poi.hssf.usermodel.HSSFWorkbook) {
- org.apache.poi.hssf.usermodel.HSSFWorkbook hssfWb =
- (org.apache.poi.hssf.usermodel.HSSFWorkbook)_workbook;
- NameRecord nameRecord = hssfWb.getNameRecord(nameIndex);
+ if(_workbook instanceof org.apache.poi.hssf.usermodel.HSSFWorkbook) {
+ NameRecord nameRecord = ((org.apache.poi.hssf.usermodel.HSSFWorkbook)_workbook).getNameRecord(nameIndex);
if (nameRecord.isFunctionName()) {
return new NameEval(nameRecord.getNameText());
}
if (nameRecord.hasFormula()) {
- return evaluateNameFormula(nameRecord.getNameDefinition(), sheet);
+ return evaluateNameFormula(nameRecord.getNameDefinition(), sheetIndex);
}
- throw new RuntimeException("Don't know how to evalate name '" + nameRecord.getNameText() + "'");
- } else {
- throw new RuntimeException("Don't know how to evaluate name records for XSSF");
+
+ throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'");
}
+ throw new RuntimeException("Don't now how to evalate name for XSSFWorkbook");
}
if (ptg instanceof NameXPtg) {
NameXPtg nameXPtg = (NameXPtg) ptg;
return new NameXEval(nameXPtg.getSheetRefIndex(), nameXPtg.getNameIndex());
}
- if (ptg instanceof RefPtg) {
- return new LazyRefEval(((RefPtg) ptg), sheet, this);
- }
- if (ptg instanceof Ref3DPtg) {
- Ref3DPtg refPtg = (Ref3DPtg) ptg;
- Sheet xsheet = getOtherSheet(refPtg.getExternSheetIndex());
- return new LazyRefEval(refPtg, xsheet, createEvaluatorForAnotherSheet(xsheet));
- }
- if (ptg instanceof AreaPtg) {
- return new LazyAreaEval(((AreaPtg) ptg), sheet, this);
- }
- if (ptg instanceof Area3DPtg) {
- Area3DPtg a3dp = (Area3DPtg) ptg;
- Sheet xsheet = getOtherSheet(a3dp.getExternSheetIndex());
- return new LazyAreaEval(a3dp, xsheet, createEvaluatorForAnotherSheet(xsheet));
- }
if (ptg instanceof IntPtg) {
return new NumberEval(((IntPtg)ptg).getValue());
@@ -550,17 +512,38 @@
if (ptg instanceof ErrPtg) {
return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode());
}
+ Sheet sheet = _workbook.getSheetAt(sheetIndex);
+ if (ptg instanceof RefPtg) {
+ return new LazyRefEval(((RefPtg) ptg), sheet, this);
+ }
+ if (ptg instanceof AreaPtg) {
+ return new LazyAreaEval(((AreaPtg) ptg), sheet, this);
+ }
+ if (ptg instanceof Ref3DPtg) {
+ Ref3DPtg refPtg = (Ref3DPtg) ptg;
+ Sheet xsheet = getOtherSheet(refPtg.getExternSheetIndex());
+ return new LazyRefEval(refPtg, xsheet, this);
+ }
+ if (ptg instanceof Area3DPtg) {
+ Area3DPtg a3dp = (Area3DPtg) ptg;
+ Sheet xsheet = getOtherSheet(a3dp.getExternSheetIndex());
+ return new LazyAreaEval(a3dp, xsheet, this);
+ }
+
if (ptg instanceof UnknownPtg) {
- // TODO - remove UnknownPtg
+ // POI uses UnknownPtg when the encoded Ptg array seems to be corrupted.
+ // This seems to occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790)
+ // In any case, formulas are re-parsed before execution, so UnknownPtg should not get here
throw new RuntimeException("UnknownPtg not allowed");
}
+
throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
}
- private Eval evaluateNameFormula(Ptg[] ptgs, Sheet sheet) {
+ private Eval evaluateNameFormula(Ptg[] ptgs, int sheetIndex) {
if (ptgs.length > 1) {
throw new RuntimeException("Complex name formulas not supported yet");
}
- return getEvalForPtg(ptgs[0], sheet);
+ return getEvalForPtg(ptgs[0], sheetIndex);
}
/**
@@ -568,11 +551,8 @@
* impl instance and return that. Since the cell could be an external
* reference, we need the sheet that this belongs to.
* Non existent cells are treated as empty.
- * @param cell
- * @param sheet
- * @param workbook
*/
- public ValueEval getEvalForCell(Cell cell, Sheet sheet) {
+ public ValueEval getEvalForCell(Cell cell) {
if (cell == null) {
return BlankEval.INSTANCE;
@@ -583,7 +563,7 @@
case Cell.CELL_TYPE_STRING:
return new StringEval(cell.getRichStringCellValue().getString());
case Cell.CELL_TYPE_FORMULA:
- return internalEvaluate(cell, sheet);
+ return internalEvaluate(cell);
case Cell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue());
case Cell.CELL_TYPE_BLANK:
@@ -600,93 +580,99 @@
* or Number or boolean type.
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/
- public static class CellValue {
- private CreationHelper creationHelper;
- private int cellType;
- private RichTextString richTextStringValue;
- private double numberValue;
- private boolean booleanValue;
- private byte errorValue;
-
- /**
- * CellType should be one of the types defined in Cell
- * @param cellType
- */
- public CellValue(int cellType, CreationHelper creationHelper) {
- super();
- this.creationHelper = creationHelper;
- this.cellType = cellType;
+ public static final class CellValue {
+ public static final CellValue TRUE = new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0, null);
+ public static final CellValue FALSE= new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0, null);
+
+ private final int _cellType;
+ private final double _numberValue;
+ private final boolean _booleanValue;
+ private final String _textValue;
+ private final int _errorCode;
+ private CreationHelper _creationHelper;
+
+ private CellValue(int cellType, double numberValue, boolean booleanValue,
+ String textValue, int errorCode, CreationHelper creationHelper) {
+ _cellType = cellType;
+ _numberValue = numberValue;
+ _booleanValue = booleanValue;
+ _textValue = textValue;
+ _errorCode = errorCode;
+ _creationHelper = creationHelper;
+ }
+
+
+ /* package*/ CellValue(double numberValue, CreationHelper creationHelper) {
+ this(Cell.CELL_TYPE_NUMERIC, numberValue, false, null, 0, creationHelper);
+ }
+ /* package*/ static CellValue valueOf(boolean booleanValue) {
+ return booleanValue ? TRUE : FALSE;
}
+ /* package*/ CellValue(String stringValue, CreationHelper creationHelper) {
+ this(Cell.CELL_TYPE_STRING, 0.0, false, stringValue, 0, creationHelper);
+ }
+ /* package*/ static CellValue getError(int errorCode) {
+ return new CellValue(Cell.CELL_TYPE_ERROR, 0.0, false, null, errorCode, null);
+ }
+
+
/**
* @return Returns the booleanValue.
*/
public boolean getBooleanValue() {
- return booleanValue;
- }
- /**
- * @param booleanValue The booleanValue to set.
- */
- public void setBooleanValue(boolean booleanValue) {
- this.booleanValue = booleanValue;
+ return _booleanValue;
}
/**
* @return Returns the numberValue.
*/
public double getNumberValue() {
- return numberValue;
- }
- /**
- * @param numberValue The numberValue to set.
- */
- public void setNumberValue(double numberValue) {
- this.numberValue = numberValue;
+ return _numberValue;
}
/**
- * @return Returns the stringValue. This method is deprecated, use
- * getRichTextStringValue instead
- * @deprecated
+ * @return Returns the stringValue.
*/
public String getStringValue() {
- return richTextStringValue.getString();
- }
- /**
- * @param stringValue The stringValue to set. This method is deprecated, use
- * getRichTextStringValue instead.
- * @deprecated
- */
- public void setStringValue(String stringValue) {
- this.richTextStringValue =
- creationHelper.createRichTextString(stringValue);
+ return _textValue;
}
/**
* @return Returns the cellType.
*/
public int getCellType() {
- return cellType;
+ return _cellType;
}
/**
* @return Returns the errorValue.
*/
public byte getErrorValue() {
- return errorValue;
- }
- /**
- * @param errorValue The errorValue to set.
- */
- public void setErrorValue(byte errorValue) {
- this.errorValue = errorValue;
+ return (byte) _errorCode;
}
/**
* @return Returns the richTextStringValue.
+ * @deprecated (Sep 2008) Text formatting is lost during formula evaluation. Use {@link #getStringValue()}
*/
public RichTextString getRichTextStringValue() {
- return richTextStringValue;
+ return _creationHelper.createRichTextString(_textValue);
}
- /**
- * @param richTextStringValue The richTextStringValue to set.
- */
- public void setRichTextStringValue(RichTextString richTextStringValue) {
- this.richTextStringValue = richTextStringValue;
+ public String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public String formatAsString() {
+ switch (_cellType) {
+ case Cell.CELL_TYPE_NUMERIC:
+ return String.valueOf(_numberValue);
+ case Cell.CELL_TYPE_STRING:
+ return '"' + _textValue + '"';
+ case Cell.CELL_TYPE_BOOLEAN:
+ return _booleanValue ? "TRUE" : "FALSE";
+ case Cell.CELL_TYPE_ERROR:
+ return ErrorEval.getText(_errorCode);
+ }
+ return "<error unexpected cell type " + _cellType + ">";
}
}
}
Added: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyAreaEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyAreaEval.java?rev=694947&view=auto
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyAreaEval.java (added)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyAreaEval.java Sat Sep 13 06:48:27 2008
@@ -0,0 +1,79 @@
+/* ====================================================================
+ 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 org.apache.poi.hssf.record.formula.AreaI;
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
+import org.apache.poi.hssf.record.formula.eval.AreaEvalBase;
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.util.CellReference;
+
+/**
+ *
+ * @author Josh Micich
+ */
+public class LazyAreaEval extends AreaEvalBase {
+
+ private final Sheet _sheet;
+ private FormulaEvaluator _evaluator;
+
+ public LazyAreaEval(AreaI ptg, Sheet sheet, FormulaEvaluator evaluator) {
+ super(ptg);
+ _sheet = sheet;
+ _evaluator = evaluator;
+ }
+
+ public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
+
+ int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
+ int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
+
+ Row row = _sheet.getRow(rowIx);
+ if (row == null) {
+ return BlankEval.INSTANCE;
+ }
+ Cell cell = row.getCell(colIx);
+ if (cell == null) {
+ return BlankEval.INSTANCE;
+ }
+ return _evaluator.getEvalForCell(cell);
+ }
+
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+ return new LazyAreaEval(area, _sheet, _evaluator);
+ }
+ public String toString() {
+ CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
+ CellReference crB = new CellReference(getLastRow(), getLastColumn());
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName()).append("[");
+ String sheetName = _evaluator.getSheetName(_sheet);
+ sb.append(sheetName);
+ sb.append('!');
+ sb.append(crA.formatAsString());
+ sb.append(':');
+ sb.append(crB.formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Propchange: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyAreaEval.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyRefEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyRefEval.java?rev=694947&view=auto
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyRefEval.java (added)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyRefEval.java Sat Sep 13 06:48:27 2008
@@ -0,0 +1,85 @@
+/* ====================================================================
+ 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 org.apache.poi.hssf.record.formula.AreaI;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.util.CellReference;
+
+/**
+*
+* @author Josh Micich
+*/
+public class LazyRefEval extends RefEvalBase {
+
+ private final Sheet _sheet;
+ private final FormulaEvaluator _evaluator;
+
+
+ public LazyRefEval(RefPtg ptg, Sheet sheet, FormulaEvaluator evaluator) {
+ super(ptg.getRow(), ptg.getColumn());
+ _sheet = sheet;
+ _evaluator = evaluator;
+ }
+ public LazyRefEval(Ref3DPtg ptg, Sheet sheet, FormulaEvaluator evaluator) {
+ super(ptg.getRow(), ptg.getColumn());
+ _sheet = sheet;
+ _evaluator = evaluator;
+ }
+
+ public ValueEval getInnerValueEval() {
+ int rowIx = getRow();
+ int colIx = getColumn();
+
+ Row row = _sheet.getRow(rowIx);
+ if (row == null) {
+ return BlankEval.INSTANCE;
+ }
+ Cell cell = row.getCell(colIx);
+ if (cell == null) {
+ return BlankEval.INSTANCE;
+ }
+ return _evaluator.getEvalForCell(cell);
+ }
+
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+
+ AreaI area = new OffsetArea(getRow(), getColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+ return new LazyAreaEval(area, _sheet, _evaluator);
+ }
+
+ public String toString() {
+ CellReference cr = new CellReference(getRow(), getColumn());
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName()).append("[");
+ String sheetName = _evaluator.getSheetName(_sheet);
+ sb.append(sheetName);
+ sb.append('!');
+ sb.append(cr.formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Propchange: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/LazyRefEval.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java Sat Sep 13 06:48:27 2008
@@ -255,8 +255,10 @@
retVal.append('[');
for(int x = 0; x < value.length; x++)
{
+ if (x>0) {
+ retVal.append(", ");
+ }
retVal.append(toHex(value[x]));
- retVal.append(", ");
}
retVal.append(']');
return retVal.toString();
Modified: poi/branches/ooxml/src/java/org/apache/poi/util/HexRead.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/util/HexRead.java?rev=694947&r1=694946&r2=694947&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/util/HexRead.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/util/HexRead.java Sat Sep 13 06:48:27 2008
@@ -172,9 +172,12 @@
return rval;
}
- static public byte[] readFromString(String data) throws IOException
- {
- return readData(new ByteArrayInputStream( data.getBytes() ), -1);
+ static public byte[] readFromString(String data) {
+ try {
+ return readData(new ByteArrayInputStream( data.getBytes() ), -1);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
static private void readToEOL( InputStream stream ) throws IOException
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org