2008-01-16 11:08:22 -05:00
|
|
|
/* ====================================================================
|
|
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
|
|
this work for additional information regarding copyright ownership.
|
|
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
|
|
(the "License"); you may not use this file except in compliance with
|
|
|
|
the License. You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
==================================================================== */
|
|
|
|
|
|
|
|
package org.apache.poi.xssf.usermodel;
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
import java.text.DateFormat;
|
|
|
|
import java.text.SimpleDateFormat;
|
2008-01-16 11:08:22 -05:00
|
|
|
import java.util.Calendar;
|
|
|
|
import java.util.Date;
|
|
|
|
|
2008-12-22 14:32:44 -05:00
|
|
|
import org.apache.poi.hssf.record.SharedFormulaRecord;
|
2009-11-03 18:02:06 -05:00
|
|
|
import org.apache.poi.hssf.record.formula.Ptg;
|
|
|
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
|
|
|
import org.apache.poi.ss.SpreadsheetVersion;
|
2008-12-04 13:38:00 -05:00
|
|
|
import org.apache.poi.ss.formula.FormulaParser;
|
2008-12-22 14:32:44 -05:00
|
|
|
import org.apache.poi.ss.formula.FormulaRenderer;
|
2009-11-03 18:02:06 -05:00
|
|
|
import org.apache.poi.ss.formula.FormulaType;
|
|
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
import org.apache.poi.ss.usermodel.CellStyle;
|
|
|
|
import org.apache.poi.ss.usermodel.Comment;
|
|
|
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
|
|
|
import org.apache.poi.ss.usermodel.DateUtil;
|
|
|
|
import org.apache.poi.ss.usermodel.FormulaError;
|
|
|
|
import org.apache.poi.ss.usermodel.Hyperlink;
|
|
|
|
import org.apache.poi.ss.usermodel.RichTextString;
|
|
|
|
import org.apache.poi.ss.util.CellReference;
|
2008-10-19 08:54:40 -04:00
|
|
|
import org.apache.poi.xssf.model.SharedStringsTable;
|
2009-11-03 18:02:06 -05:00
|
|
|
import org.apache.poi.xssf.model.StylesTable;
|
2008-01-16 11:08:22 -05:00
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
|
2008-12-22 14:32:44 -05:00
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
|
2009-11-03 18:02:06 -05:00
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType;
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-04-06 16:27:40 -04:00
|
|
|
/**
|
2008-10-23 14:57:28 -04:00
|
|
|
* High level representation of a cell in a row of a spreadsheet.
|
|
|
|
* <p>
|
|
|
|
* 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.
|
|
|
|
* </p>
|
|
|
|
* <p>
|
|
|
|
* Cells should have their number (0 based) before being added to a row. Only
|
|
|
|
* cells that have values should be added.
|
|
|
|
* </p>
|
2008-04-06 16:27:40 -04:00
|
|
|
*/
|
|
|
|
public final class XSSFCell implements Cell {
|
2008-01-16 11:08:22 -05:00
|
|
|
|
|
|
|
private static final String FALSE_AS_STRING = "0";
|
|
|
|
private static final String TRUE_AS_STRING = "1";
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* the xml bean containing information about the cell's location, value,
|
|
|
|
* data type, formatting, and formula
|
|
|
|
*/
|
2009-08-18 12:50:24 -04:00
|
|
|
private final CTCell _cell;
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* the XSSFRow this cell belongs to
|
|
|
|
*/
|
2009-08-18 12:50:24 -04:00
|
|
|
private final XSSFRow _row;
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 0-based column index
|
|
|
|
*/
|
2009-08-18 12:50:24 -04:00
|
|
|
private int _cellNum;
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Table of strings shared across this workbook.
|
|
|
|
* If two cells contain the same string, then the cell value is the same index into SharedStringsTable
|
|
|
|
*/
|
2009-08-18 12:50:24 -04:00
|
|
|
private SharedStringsTable _sharedStringSource;
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Table of cell styles shared across all cells in a workbook.
|
|
|
|
*/
|
2009-08-18 12:50:24 -04:00
|
|
|
private StylesTable _stylesSource;
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Construct a XSSFCell.
|
|
|
|
*
|
|
|
|
* @param row the parent row.
|
2008-11-07 11:57:23 -05:00
|
|
|
* @param cell the xml bean containing information about the cell.
|
2008-10-23 14:57:28 -04:00
|
|
|
*/
|
|
|
|
protected XSSFCell(XSSFRow row, CTCell cell) {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell = cell;
|
|
|
|
_row = row;
|
2008-02-07 10:44:32 -05:00
|
|
|
if (cell.getR() != null) {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cellNum = new CellReference(cell.getR()).getCol();
|
2008-02-07 10:44:32 -05:00
|
|
|
}
|
2009-08-18 12:50:24 -04:00
|
|
|
_sharedStringSource = row.getSheet().getWorkbook().getSharedStringSource();
|
|
|
|
_stylesSource = row.getSheet().getWorkbook().getStylesSource();
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* @return table of strings shared across this workbook
|
|
|
|
*/
|
2008-10-19 08:54:40 -04:00
|
|
|
protected SharedStringsTable getSharedStringSource() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _sharedStringSource;
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-12-22 14:32:44 -05:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* @return table of cell styles shared across this workbook
|
|
|
|
*/
|
|
|
|
protected StylesTable getStylesSource() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _stylesSource;
|
2008-03-16 20:10:17 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Returns the sheet this cell belongs to
|
|
|
|
*
|
|
|
|
* @return the sheet this cell belongs to
|
|
|
|
*/
|
|
|
|
public XSSFSheet getSheet() {
|
2008-12-22 14:32:44 -05:00
|
|
|
return getRow().getSheet();
|
|
|
|
}
|
2008-09-13 09:56:04 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Returns the row this cell belongs to
|
|
|
|
*
|
|
|
|
* @return the row this cell belongs to
|
|
|
|
*/
|
|
|
|
public XSSFRow getRow() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _row;
|
2008-12-22 14:32:44 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the value of the cell as a boolean.
|
|
|
|
* <p>
|
|
|
|
* For strings, numbers, and errors, we throw an exception. For blank cells we return a false.
|
|
|
|
* </p>
|
|
|
|
* @return the value of the cell as a boolean
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()}
|
|
|
|
* is not CELL_TYPE_BOOLEAN, CELL_TYPE_BLANK or CELL_TYPE_FORMULA
|
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public boolean getBooleanCellValue() {
|
2008-10-23 14:57:28 -04:00
|
|
|
int cellType = getCellType();
|
|
|
|
switch(cellType) {
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
return false;
|
|
|
|
case CELL_TYPE_BOOLEAN:
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.isSetV() && TRUE_AS_STRING.equals(_cell.getV());
|
2008-10-23 14:57:28 -04:00
|
|
|
case CELL_TYPE_FORMULA:
|
|
|
|
//YK: should throw an exception if requesting boolean value from a non-boolean formula
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.isSetV() && TRUE_AS_STRING.equals(_cell.getV());
|
2008-10-23 14:57:28 -04:00
|
|
|
default:
|
|
|
|
throw typeMismatch(CELL_TYPE_BOOLEAN, cellType, false);
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a boolean value for the cell
|
|
|
|
*
|
|
|
|
* @param value the boolean value to set this cell to. For formulas we'll set the
|
|
|
|
* precalculated value, for booleans we'll set its value. For other types we
|
|
|
|
* will change the cell to a boolean cell and set its value.
|
|
|
|
*/
|
|
|
|
public void setCellValue(boolean value) {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.B);
|
|
|
|
_cell.setV(value ? TRUE_AS_STRING : FALSE_AS_STRING);
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the value of the cell as a number.
|
|
|
|
* <p>
|
|
|
|
* For strings we throw an exception. For blank cells we return a 0.
|
|
|
|
* For formulas or error cells we return the precalculated value;
|
|
|
|
* </p>
|
|
|
|
* @return the value of the cell as a number
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CELL_TYPE_STRING
|
|
|
|
* @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
|
2008-10-29 15:12:47 -04:00
|
|
|
* @see DataFormatter for turning this number into a string similar to that which Excel would render this number as.
|
2008-10-23 14:57:28 -04:00
|
|
|
*/
|
|
|
|
public double getNumericCellValue() {
|
|
|
|
int cellType = getCellType();
|
|
|
|
switch(cellType) {
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
return 0.0;
|
|
|
|
case CELL_TYPE_FORMULA:
|
|
|
|
case CELL_TYPE_NUMERIC:
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.isSetV() ? Double.parseDouble(_cell.getV()) : 0.0;
|
2008-10-23 14:57:28 -04:00
|
|
|
default:
|
|
|
|
throw typeMismatch(CELL_TYPE_NUMERIC, cellType, false);
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Set a numeric value for the cell
|
|
|
|
*
|
|
|
|
* @param value the numeric value to set this cell to. For formulas we'll set the
|
|
|
|
* 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) {
|
2009-03-22 11:12:11 -04:00
|
|
|
if(Double.isInfinite(value) || Double.isNaN(value)) {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.E);
|
|
|
|
_cell.setV(FormulaError.NUM.getString());
|
2009-03-22 11:12:11 -04:00
|
|
|
} else {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.N);
|
|
|
|
_cell.setV(String.valueOf(value));
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Get the value of the cell as a string
|
|
|
|
* <p>
|
|
|
|
* For numeric cells we throw an exception. For blank cells we return an empty string.
|
|
|
|
* For formulaCells that are not string Formulas, we return empty String.
|
|
|
|
* </p>
|
|
|
|
* @return the value of the cell as a string
|
|
|
|
*/
|
|
|
|
public String getStringCellValue() {
|
|
|
|
XSSFRichTextString str = getRichStringCellValue();
|
|
|
|
return str == null ? null : str.getString();
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Get the value of the cell as a XSSFRichTextString
|
|
|
|
* <p>
|
|
|
|
* For numeric cells we throw an exception. For blank cells we return an empty string.
|
|
|
|
* For formula cells we return the pre-calculated value.
|
|
|
|
* </p>
|
|
|
|
* @return the value of the cell as a XSSFRichTextString
|
|
|
|
*/
|
|
|
|
public XSSFRichTextString getRichStringCellValue() {
|
|
|
|
int cellType = getCellType();
|
|
|
|
XSSFRichTextString rt;
|
|
|
|
switch (cellType) {
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
rt = new XSSFRichTextString("");
|
|
|
|
break;
|
|
|
|
case CELL_TYPE_STRING:
|
2009-08-18 12:50:24 -04:00
|
|
|
if (_cell.getT() == STCellType.INLINE_STR) {
|
|
|
|
if(_cell.isSetIs()) {
|
2009-05-23 04:20:55 -04:00
|
|
|
//string is expressed directly in the cell definition instead of implementing the shared string table.
|
2009-08-18 12:50:24 -04:00
|
|
|
rt = new XSSFRichTextString(_cell.getIs());
|
|
|
|
} else if (_cell.isSetV()) {
|
2009-05-23 04:20:55 -04:00
|
|
|
//cached result of a formula
|
2009-08-18 12:50:24 -04:00
|
|
|
rt = new XSSFRichTextString(_cell.getV());
|
2008-10-23 14:57:28 -04:00
|
|
|
} else {
|
2009-05-23 04:20:55 -04:00
|
|
|
rt = new XSSFRichTextString("");
|
|
|
|
}
|
2009-09-26 06:41:01 -04:00
|
|
|
} else if (_cell.getT() == STCellType.STR) {
|
|
|
|
//cached formula value
|
|
|
|
rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : "");
|
2009-05-23 04:20:55 -04:00
|
|
|
} else {
|
2009-08-18 12:50:24 -04:00
|
|
|
if (_cell.isSetV()) {
|
|
|
|
int idx = Integer.parseInt(_cell.getV());
|
|
|
|
rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(idx));
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
2009-05-23 04:20:55 -04:00
|
|
|
else {
|
|
|
|
rt = new XSSFRichTextString("");
|
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CELL_TYPE_FORMULA:
|
2009-08-18 12:50:24 -04:00
|
|
|
rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : "");
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw typeMismatch(CELL_TYPE_STRING, cellType, false);
|
|
|
|
}
|
2009-08-18 12:50:24 -04:00
|
|
|
rt.setStylesTableReference(_stylesSource);
|
2008-10-23 14:57:28 -04:00
|
|
|
return rt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a string value for the cell.
|
|
|
|
*
|
|
|
|
* @param str value to set the cell to. For formulas we'll set the formula
|
|
|
|
* cached string result, for String cells we'll set its value. For other types we will
|
|
|
|
* change the cell to a string cell and set its value.
|
|
|
|
* If value is null then we will change the cell to a Blank cell.
|
|
|
|
*/
|
|
|
|
public void setCellValue(String str) {
|
|
|
|
setCellValue(str == null ? null : new XSSFRichTextString(str));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a string value for the cell.
|
|
|
|
*
|
|
|
|
* @param str value to set the cell to. For formulas we'll set the 'pre-evaluated result string,
|
|
|
|
* for String cells we'll set its value. For other types we will
|
|
|
|
* change the cell to a string cell and set its value.
|
|
|
|
* If value is null then we will change the cell to a Blank cell.
|
|
|
|
*/
|
|
|
|
public void setCellValue(RichTextString str) {
|
2009-05-30 06:37:08 -04:00
|
|
|
if(str == null || str.getString() == null){
|
2008-10-23 14:57:28 -04:00
|
|
|
setBlank();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int cellType = getCellType();
|
|
|
|
switch(cellType){
|
|
|
|
case Cell.CELL_TYPE_FORMULA:
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setV(str.getString());
|
|
|
|
_cell.setT(STCellType.STR);
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
default:
|
2009-08-18 12:50:24 -04:00
|
|
|
if(_cell.getT() == STCellType.INLINE_STR) {
|
2008-10-23 14:57:28 -04:00
|
|
|
//set the 'pre-evaluated result
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setV(str.getString());
|
2008-10-23 14:57:28 -04:00
|
|
|
} else {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.S);
|
2008-10-23 14:57:28 -04:00
|
|
|
XSSFRichTextString rt = (XSSFRichTextString)str;
|
2009-08-18 12:50:24 -04:00
|
|
|
rt.setStylesTableReference(_stylesSource);
|
|
|
|
int sRef = _sharedStringSource.addEntry(rt.getCTRst());
|
|
|
|
_cell.setV(Integer.toString(sRef));
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
break;
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
|
|
|
|
*
|
|
|
|
* @return a formula for the cell
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} is not CELL_TYPE_FORMULA
|
|
|
|
*/
|
|
|
|
public String getCellFormula() {
|
|
|
|
int cellType = getCellType();
|
|
|
|
if(cellType != CELL_TYPE_FORMULA) throw typeMismatch(CELL_TYPE_FORMULA, cellType, false);
|
|
|
|
|
2009-08-18 12:50:24 -04:00
|
|
|
CTCellFormula f = _cell.getF();
|
2008-12-22 14:32:44 -05:00
|
|
|
if(f.getT() == STCellFormulaType.SHARED){
|
|
|
|
return convertSharedFormula((int)f.getSi());
|
|
|
|
}
|
2009-08-18 12:50:24 -04:00
|
|
|
return f.getStringValue();
|
2008-12-22 14:32:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a non shared formula from the shared formula counterpart
|
|
|
|
*
|
|
|
|
* @return non shared formula created for the given shared formula and this cell
|
|
|
|
*/
|
|
|
|
private String convertSharedFormula(int idx){
|
|
|
|
XSSFSheet sheet = getSheet();
|
|
|
|
XSSFCell sfCell = sheet.getSharedFormulaCell(idx);
|
|
|
|
if(sfCell == null){
|
|
|
|
throw new IllegalStateException("Shared Formula not found for group index " + idx);
|
|
|
|
}
|
|
|
|
String sharedFormula = sfCell.getCTCell().getF().getStringValue();
|
2008-12-23 11:19:07 -05:00
|
|
|
int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
|
2008-12-22 14:32:44 -05:00
|
|
|
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(sheet.getWorkbook());
|
2008-12-23 11:19:07 -05:00
|
|
|
Ptg[] ptgs = FormulaParser.parse(sharedFormula, fpb, FormulaType.CELL, sheetIndex);
|
2008-12-22 14:32:44 -05:00
|
|
|
Ptg[] fmla = SharedFormulaRecord.convertSharedFormulas(ptgs,
|
|
|
|
getRowIndex() - sfCell.getRowIndex(), getColumnIndex() - sfCell.getColumnIndex());
|
|
|
|
return FormulaRenderer.toFormulaString(fpb, fmla);
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
public void setCellFormula(String formula) {
|
2009-08-18 12:50:24 -04:00
|
|
|
XSSFWorkbook wb = _row.getSheet().getWorkbook();
|
2009-04-20 12:50:05 -04:00
|
|
|
if (formula == null) {
|
2009-02-08 07:45:55 -05:00
|
|
|
wb.onDeleteFormula(this);
|
2009-08-18 12:50:24 -04:00
|
|
|
if(_cell.isSetF()) _cell.unsetF();
|
2008-10-23 14:57:28 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-12-23 11:19:07 -05:00
|
|
|
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
|
2009-04-18 03:12:38 -04:00
|
|
|
//validate through the FormulaParser
|
|
|
|
FormulaParser.parse(formula, fpb, FormulaType.CELL, wb.getSheetIndex(getSheet()));
|
2008-12-04 13:38:00 -05:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
CTCellFormula f = CTCellFormula.Factory.newInstance();
|
|
|
|
f.setStringValue(formula);
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setF(f);
|
|
|
|
if(_cell.isSetV()) _cell.unsetV();
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns column index of this cell
|
|
|
|
*
|
|
|
|
* @return zero-based column index of a column in a sheet.
|
|
|
|
*/
|
2008-10-09 04:03:43 -04:00
|
|
|
public int getColumnIndex() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return this._cellNum;
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns row index of a row in the sheet that contains this cell
|
|
|
|
*
|
|
|
|
* @return zero-based row index of a row in the sheet that contains this cell
|
|
|
|
*/
|
|
|
|
public int getRowIndex() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _row.getRowNum();
|
2008-12-22 14:32:44 -05:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Returns an A1 style reference to the location of this cell
|
|
|
|
*
|
|
|
|
* @return A1 style reference to the location of this cell
|
|
|
|
*/
|
|
|
|
public String getReference() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.getR();
|
2008-12-22 14:32:44 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
2008-10-21 13:56:34 -04:00
|
|
|
/**
|
|
|
|
* Return the cell's style.
|
|
|
|
*
|
2009-09-26 06:41:01 -04:00
|
|
|
* @return the cell's style.</code>
|
2008-10-21 13:56:34 -04:00
|
|
|
*/
|
2008-09-25 02:51:18 -04:00
|
|
|
public XSSFCellStyle getCellStyle() {
|
2009-09-26 06:41:01 -04:00
|
|
|
XSSFCellStyle style = null;
|
|
|
|
if(_stylesSource.getNumCellStyles() > 0){
|
|
|
|
long idx = _cell.isSetS() ? _cell.getS() : 0;
|
|
|
|
style = _stylesSource.getStyleAt((int)idx);
|
|
|
|
}
|
|
|
|
return style;
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Set the style for the cell. The style should be an XSSFCellStyle created/retreived from
|
|
|
|
* the XSSFWorkbook.
|
|
|
|
*
|
|
|
|
* @param style reference contained in the workbook.
|
|
|
|
* If the value is null then the style information is removed causing the cell to used the default workbook style.
|
|
|
|
*/
|
|
|
|
public void setCellStyle(CellStyle style) {
|
|
|
|
if(style == null) {
|
2009-08-18 12:50:24 -04:00
|
|
|
if(_cell.isSetS()) _cell.unsetS();
|
2008-10-23 14:57:28 -04:00
|
|
|
} else {
|
2008-12-22 14:32:44 -05:00
|
|
|
XSSFCellStyle xStyle = (XSSFCellStyle)style;
|
2009-08-18 12:50:24 -04:00
|
|
|
xStyle.verifyBelongsToStylesSource(_stylesSource);
|
2008-10-23 14:57:28 -04:00
|
|
|
|
2009-08-18 12:50:24 -04:00
|
|
|
long idx = _stylesSource.putStyle(xStyle);
|
|
|
|
_cell.setS(idx);
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the cell type.
|
|
|
|
*
|
|
|
|
* @return the cell type
|
|
|
|
* @see Cell#CELL_TYPE_BLANK
|
|
|
|
* @see Cell#CELL_TYPE_NUMERIC
|
|
|
|
* @see Cell#CELL_TYPE_STRING
|
|
|
|
* @see Cell#CELL_TYPE_FORMULA
|
|
|
|
* @see Cell#CELL_TYPE_BOOLEAN
|
|
|
|
* @see Cell#CELL_TYPE_ERROR
|
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public int getCellType() {
|
2008-10-23 14:57:28 -04:00
|
|
|
|
2009-08-18 12:50:24 -04:00
|
|
|
if (_cell.getF() != null) {
|
2008-04-06 16:27:40 -04:00
|
|
|
return CELL_TYPE_FORMULA;
|
|
|
|
}
|
|
|
|
|
2009-03-22 11:12:11 -04:00
|
|
|
return getBaseCellType(true);
|
2009-02-19 12:29:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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() {
|
2009-08-18 12:50:24 -04:00
|
|
|
if (_cell.getF() == null) {
|
2009-02-19 12:29:55 -05:00
|
|
|
throw new IllegalStateException("Only formula cells have cached results");
|
|
|
|
}
|
|
|
|
|
2009-03-22 11:12:11 -04:00
|
|
|
return getBaseCellType(false);
|
2009-02-19 12:29:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Detect cell type based on the "t" attribute of the CTCell bean
|
|
|
|
*/
|
2009-03-22 11:12:11 -04:00
|
|
|
private int getBaseCellType(boolean blankCells) {
|
2009-08-18 12:50:24 -04:00
|
|
|
switch (_cell.getT().intValue()) {
|
2008-10-23 14:57:28 -04:00
|
|
|
case STCellType.INT_B:
|
|
|
|
return CELL_TYPE_BOOLEAN;
|
|
|
|
case STCellType.INT_N:
|
2009-08-18 12:50:24 -04:00
|
|
|
if (!_cell.isSetV() && blankCells) {
|
2008-10-23 14:57:28 -04:00
|
|
|
// ooxml does have a separate cell type of 'blank'. A blank cell gets encoded as
|
|
|
|
// (either not present or) a numeric cell with no value set.
|
|
|
|
// The formula evaluator (and perhaps other clients of this interface) needs to
|
|
|
|
// distinguish blank values which sometimes get translated into zero and sometimes
|
|
|
|
// empty string, depending on context
|
|
|
|
return CELL_TYPE_BLANK;
|
|
|
|
}
|
|
|
|
return CELL_TYPE_NUMERIC;
|
|
|
|
case STCellType.INT_E:
|
|
|
|
return CELL_TYPE_ERROR;
|
|
|
|
case STCellType.INT_S: // String is in shared strings
|
|
|
|
case STCellType.INT_INLINE_STR: // String is inline in cell
|
|
|
|
case STCellType.INT_STR:
|
2009-02-08 07:45:55 -05:00
|
|
|
return CELL_TYPE_STRING;
|
2008-10-23 14:57:28 -04:00
|
|
|
default:
|
2009-08-18 12:50:24 -04:00
|
|
|
throw new IllegalStateException("Illegal cell type: " + this._cell.getT());
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Get the value of the cell as a date.
|
|
|
|
* <p>
|
|
|
|
* For strings we throw an exception. For blank cells we return a null.
|
|
|
|
* </p>
|
|
|
|
* @return the value of the cell as a date
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CELL_TYPE_STRING
|
|
|
|
* @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
|
2008-10-29 15:12:47 -04:00
|
|
|
* @see DataFormatter for formatting this date into a string similar to how excel does.
|
2008-10-23 14:57:28 -04:00
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public Date getDateCellValue() {
|
2008-10-23 14:57:28 -04:00
|
|
|
int cellType = getCellType();
|
|
|
|
if (cellType == CELL_TYPE_BLANK) {
|
|
|
|
return null;
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
double value = getNumericCellValue();
|
|
|
|
boolean date1904 = getSheet().getWorkbook().isDate1904();
|
|
|
|
return DateUtil.getJavaDate(value, date1904);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
|
|
|
|
* a date.
|
|
|
|
*
|
|
|
|
* @param value the date value to set this cell to. For formulas we'll set the
|
|
|
|
* 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(Date value) {
|
2008-12-22 14:32:44 -05:00
|
|
|
boolean date1904 = getSheet().getWorkbook().isDate1904();
|
2008-10-23 14:57:28 -04:00
|
|
|
setCellValue(DateUtil.getExcelDate(value, date1904));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
|
|
|
|
* a date.
|
|
|
|
* <p>
|
|
|
|
* 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
|
|
|
|
* are 6 hours difference between the two times. This difference can be
|
|
|
|
* preserved by using <code>setCellValue(value.getTime())</code> which will
|
|
|
|
* automatically shift the times to the default timezone.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @param value the date value to set this cell to. For formulas we'll set the
|
|
|
|
* precalculated value, for numerics we'll set its value. For othertypes we
|
|
|
|
* will change the cell to a numeric cell and set its value.
|
|
|
|
*/
|
|
|
|
public void setCellValue(Calendar value) {
|
2008-12-22 14:32:44 -05:00
|
|
|
boolean date1904 = getSheet().getWorkbook().isDate1904();
|
2008-10-23 14:57:28 -04:00
|
|
|
setCellValue( DateUtil.getExcelDate(value, date1904 ));
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-03-30 10:16:22 -04:00
|
|
|
/**
|
|
|
|
* Returns the error message, such as #VALUE!
|
2008-10-23 14:57:28 -04:00
|
|
|
*
|
|
|
|
* @return the error message such as #VALUE!
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} isn't CELL_TYPE_ERROR
|
|
|
|
* @see FormulaError
|
2008-03-30 10:16:22 -04:00
|
|
|
*/
|
|
|
|
public String getErrorCellString() {
|
2009-11-25 06:33:21 -05:00
|
|
|
int cellType = getBaseCellType(true);
|
2008-10-23 14:57:28 -04:00
|
|
|
if(cellType != CELL_TYPE_ERROR) throw typeMismatch(CELL_TYPE_ERROR, cellType, false);
|
|
|
|
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.getV();
|
2008-03-30 10:16:22 -04:00
|
|
|
}
|
|
|
|
/**
|
2008-10-23 14:57:28 -04:00
|
|
|
* Get the value of the cell as an error code.
|
|
|
|
* <p>
|
|
|
|
* For strings, numbers, and booleans, we throw an exception.
|
|
|
|
* For blank cells we return a 0.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @return the value of the cell as an error code
|
|
|
|
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} isn't CELL_TYPE_ERROR
|
|
|
|
* @see FormulaError
|
2008-03-30 10:16:22 -04:00
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public byte getErrorCellValue() {
|
2008-10-23 14:57:28 -04:00
|
|
|
String code = getErrorCellString();
|
2009-08-18 01:29:53 -04:00
|
|
|
if (code == null) {
|
|
|
|
return 0;
|
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2009-08-18 01:29:53 -04:00
|
|
|
return FormulaError.forString(code).getCode();
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
2008-10-23 14:57:28 -04:00
|
|
|
* Set a error value for the cell
|
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
* @see FormulaError
|
2008-10-01 13:15:02 -04:00
|
|
|
*/
|
2008-10-23 14:57:28 -04:00
|
|
|
public void setCellErrorValue(byte errorCode) {
|
|
|
|
FormulaError error = FormulaError.forInt(errorCode);
|
|
|
|
setCellErrorValue(error);
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Set a error value for the cell
|
|
|
|
*
|
|
|
|
* @param error 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(FormulaError error) {
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.E);
|
|
|
|
_cell.setV(error.getString());
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Sets this cell as the active cell for the worksheet.
|
|
|
|
*/
|
|
|
|
public void setAsActiveCell() {
|
2009-08-18 12:50:24 -04:00
|
|
|
getSheet().setActiveCell(_cell.getR());
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Blanks this cell. Blank cells have no formula or value but may have styling.
|
|
|
|
* This method erases all the data previously associated with this cell.
|
|
|
|
*/
|
|
|
|
private void setBlank(){
|
|
|
|
CTCell blank = CTCell.Factory.newInstance();
|
2009-08-18 12:50:24 -04:00
|
|
|
blank.setR(_cell.getR());
|
2009-09-26 06:41:01 -04:00
|
|
|
if(_cell.isSetS()) blank.setS(_cell.getS());
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.set(blank);
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Sets column index of this cell
|
|
|
|
*
|
|
|
|
* @param num column index of this cell
|
|
|
|
*/
|
2008-11-14 15:29:42 -05:00
|
|
|
protected void setCellNum(int num) {
|
2008-02-07 10:44:32 -05:00
|
|
|
checkBounds(num);
|
2009-08-18 12:50:24 -04:00
|
|
|
_cellNum = num;
|
2008-12-04 13:38:00 -05:00
|
|
|
String ref = new CellReference(getRowIndex(), getColumnIndex()).formatAsString();
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setR(ref);
|
2008-02-07 10:44:32 -05:00
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
2008-10-23 14:57:28 -04:00
|
|
|
* Set the cells type (numeric, formula or string)
|
|
|
|
*
|
|
|
|
* @throws IllegalArgumentException if the specified cell type is invalid
|
2008-10-01 13:15:02 -04:00
|
|
|
* @see #CELL_TYPE_NUMERIC
|
|
|
|
* @see #CELL_TYPE_STRING
|
|
|
|
* @see #CELL_TYPE_FORMULA
|
|
|
|
* @see #CELL_TYPE_BLANK
|
|
|
|
* @see #CELL_TYPE_BOOLEAN
|
|
|
|
* @see #CELL_TYPE_ERROR
|
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public void setCellType(int cellType) {
|
2009-03-22 11:12:11 -04:00
|
|
|
int prevType = getCellType();
|
2008-01-16 11:08:22 -05:00
|
|
|
switch (cellType) {
|
2008-10-23 14:57:28 -04:00
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
setBlank();
|
|
|
|
break;
|
|
|
|
case CELL_TYPE_BOOLEAN:
|
2009-03-22 11:12:11 -04:00
|
|
|
String newVal = convertCellValueToBoolean() ? TRUE_AS_STRING : FALSE_AS_STRING;
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.B);
|
|
|
|
_cell.setV(newVal);
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
case CELL_TYPE_NUMERIC:
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.N);
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
case CELL_TYPE_ERROR:
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.E);
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
case CELL_TYPE_STRING:
|
2009-03-22 11:12:11 -04:00
|
|
|
if(prevType != CELL_TYPE_STRING){
|
|
|
|
String str = convertCellValueToString();
|
|
|
|
XSSFRichTextString rt = new XSSFRichTextString(str);
|
2009-08-18 12:50:24 -04:00
|
|
|
rt.setStylesTableReference(_stylesSource);
|
|
|
|
int sRef = _sharedStringSource.addEntry(rt.getCTRst());
|
|
|
|
_cell.setV(Integer.toString(sRef));
|
2009-03-22 11:12:11 -04:00
|
|
|
}
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setT(STCellType.S);
|
2008-10-23 14:57:28 -04:00
|
|
|
break;
|
|
|
|
case CELL_TYPE_FORMULA:
|
2009-08-18 12:50:24 -04:00
|
|
|
if(!_cell.isSetF()){
|
2008-10-23 14:57:28 -04:00
|
|
|
CTCellFormula f = CTCellFormula.Factory.newInstance();
|
|
|
|
f.setStringValue("0");
|
2009-08-18 12:50:24 -04:00
|
|
|
_cell.setF(f);
|
|
|
|
if(_cell.isSetT()) _cell.unsetT();
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException("Illegal cell type: " + cellType);
|
2008-04-06 16:27:40 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
|
|
|
* Returns a string representation of the cell
|
2008-10-23 14:57:28 -04:00
|
|
|
* <p>
|
|
|
|
* Formula cells return the formula string, rather than the formula result.
|
2008-10-01 13:15:02 -04:00
|
|
|
* Dates are displayed in dd-MMM-yyyy format
|
|
|
|
* Errors are displayed as #ERR<errIdx>
|
2008-10-23 14:57:28 -04:00
|
|
|
* </p>
|
2008-10-01 13:15:02 -04:00
|
|
|
*/
|
2008-01-16 11:08:22 -05:00
|
|
|
public String toString() {
|
2008-10-01 13:15:02 -04:00
|
|
|
switch (getCellType()) {
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
return "";
|
|
|
|
case CELL_TYPE_BOOLEAN:
|
|
|
|
return getBooleanCellValue() ? "TRUE" : "FALSE";
|
|
|
|
case CELL_TYPE_ERROR:
|
|
|
|
return ErrorEval.getText(getErrorCellValue());
|
|
|
|
case CELL_TYPE_FORMULA:
|
|
|
|
return getCellFormula();
|
|
|
|
case CELL_TYPE_NUMERIC:
|
|
|
|
if (DateUtil.isCellDateFormatted(this)) {
|
|
|
|
DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
|
|
|
|
return sdf.format(getDateCellValue());
|
|
|
|
}
|
2009-08-18 12:50:24 -04:00
|
|
|
return getNumericCellValue() + "";
|
2008-10-01 13:15:02 -04:00
|
|
|
case CELL_TYPE_STRING:
|
|
|
|
return getRichStringCellValue().toString();
|
|
|
|
default:
|
|
|
|
return "Unknown Cell Type: " + getCellType();
|
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|
2008-04-06 16:27:40 -04:00
|
|
|
|
2008-03-08 13:06:41 -05:00
|
|
|
/**
|
|
|
|
* Returns the raw, underlying ooxml value for the cell
|
2008-10-23 14:57:28 -04:00
|
|
|
* <p>
|
|
|
|
* If the cell contains a string, then this value is an index into
|
|
|
|
* the shared string table, pointing to the actual string value. Otherwise,
|
|
|
|
* the value of the cell is expressed directly in this element. Cells containing formulas express
|
|
|
|
* the last calculated result of the formula in this element.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @return the raw cell value as contained in the underlying CTCell bean,
|
|
|
|
* <code>null</code> for blank cells.
|
2008-03-08 13:06:41 -05:00
|
|
|
*/
|
|
|
|
public String getRawValue() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.getV();
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 + ")#";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to help format error messages
|
|
|
|
*/
|
|
|
|
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);
|
2008-03-08 13:06:41 -05:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-02-07 10:44:32 -05:00
|
|
|
/**
|
|
|
|
* @throws RuntimeException if the bounds are exceeded.
|
|
|
|
*/
|
2009-01-16 12:31:29 -05:00
|
|
|
private static void checkBounds(int cellIndex) {
|
2009-04-06 11:06:23 -04:00
|
|
|
SpreadsheetVersion v = SpreadsheetVersion.EXCEL2007;
|
|
|
|
int maxcol = SpreadsheetVersion.EXCEL2007.getLastColumnIndex();
|
|
|
|
if (cellIndex < 0 || cellIndex > maxcol) {
|
2009-08-18 01:29:53 -04:00
|
|
|
throw new IllegalArgumentException("Invalid column index (" + cellIndex
|
2009-04-06 11:06:23 -04:00
|
|
|
+ "). Allowable column range for " + v.name() + " is (0.."
|
|
|
|
+ maxcol + ") or ('A'..'" + v.getLastColumnName() + "')");
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-02-07 10:44:32 -05:00
|
|
|
}
|
|
|
|
|
2008-10-23 14:57:28 -04:00
|
|
|
/**
|
|
|
|
* Returns cell comment associated with this cell
|
|
|
|
*
|
|
|
|
* @return the cell comment associated with this cell or <code>null</code>
|
|
|
|
*/
|
|
|
|
public XSSFComment getCellComment() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return getSheet().getCellComment(_row.getRowNum(), getColumnIndex());
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assign a comment to this cell. If the supplied comment is null,
|
|
|
|
* the comment for this cell will be removed.
|
|
|
|
*
|
2009-11-27 12:39:17 -05:00
|
|
|
* @param comment the XSSFComment associated with this cell
|
2008-10-23 14:57:28 -04:00
|
|
|
*/
|
|
|
|
public void setCellComment(Comment comment) {
|
2009-11-27 12:39:17 -05:00
|
|
|
if(comment == null) {
|
|
|
|
removeCellComment();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
comment.setRow(getRowIndex());
|
|
|
|
comment.setColumn(getColumnIndex());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the comment for this cell, if there is one.
|
|
|
|
*/
|
|
|
|
public void removeCellComment() {
|
|
|
|
XSSFComment comment = getCellComment();
|
|
|
|
if(comment != null){
|
|
|
|
String ref = _cell.getR();
|
|
|
|
XSSFSheet sh = getSheet();
|
|
|
|
sh.getCommentsTable(false).removeComment(ref);
|
|
|
|
sh.getVMLDrawing(false).removeCommentShape(getRowIndex(), getColumnIndex());
|
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns hyperlink associated with this cell
|
|
|
|
*
|
|
|
|
* @return hyperlink associated with this cell or <code>null</code> if not found
|
|
|
|
*/
|
|
|
|
public XSSFHyperlink getHyperlink() {
|
2009-08-18 12:50:24 -04:00
|
|
|
return getSheet().getHyperlink(_row.getRowNum(), _cellNum);
|
2008-12-22 14:32:44 -05:00
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Assign a hypelrink to this cell
|
|
|
|
*
|
|
|
|
* @param hyperlink the hypelrink to associate with this cell
|
|
|
|
*/
|
|
|
|
public void setHyperlink(Hyperlink hyperlink) {
|
2008-12-22 14:32:44 -05:00
|
|
|
XSSFHyperlink link = (XSSFHyperlink)hyperlink;
|
|
|
|
|
|
|
|
// Assign to us
|
2009-08-18 12:50:24 -04:00
|
|
|
link.setCellReference( new CellReference(_row.getRowNum(), _cellNum).formatAsString() );
|
2008-12-22 14:32:44 -05:00
|
|
|
|
|
|
|
// Add to the lists
|
|
|
|
getSheet().setCellHyperlink(link);
|
|
|
|
}
|
2008-10-23 14:57:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the xml bean containing information about the cell's location (reference), value,
|
|
|
|
* data type, formatting, and formula
|
|
|
|
*
|
|
|
|
* @return the xml bean containing information about this cell
|
|
|
|
*/
|
|
|
|
public CTCell getCTCell(){
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell;
|
2008-10-23 14:57:28 -04:00
|
|
|
}
|
2008-10-30 05:42:53 -04:00
|
|
|
|
2009-03-22 11:12:11 -04:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
* 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() {
|
|
|
|
int cellType = getCellType();
|
2009-08-18 01:29:53 -04:00
|
|
|
|
2009-04-11 13:53:39 -04:00
|
|
|
if (cellType == CELL_TYPE_FORMULA) {
|
|
|
|
cellType = getBaseCellType(false);
|
|
|
|
}
|
2009-03-22 11:12:11 -04:00
|
|
|
|
|
|
|
switch (cellType) {
|
|
|
|
case CELL_TYPE_BOOLEAN:
|
2009-08-18 12:50:24 -04:00
|
|
|
return TRUE_AS_STRING.equals(_cell.getV());
|
2009-03-22 11:12:11 -04:00
|
|
|
case CELL_TYPE_STRING:
|
2009-08-18 12:50:24 -04:00
|
|
|
int sstIndex = Integer.parseInt(_cell.getV());
|
|
|
|
XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex));
|
2009-03-22 11:12:11 -04:00
|
|
|
String text = rt.getString();
|
2009-11-27 15:54:03 -05:00
|
|
|
return Boolean.parseBoolean(text);
|
2009-03-22 11:12:11 -04:00
|
|
|
case CELL_TYPE_NUMERIC:
|
2009-08-18 12:50:24 -04:00
|
|
|
return Double.parseDouble(_cell.getV()) != 0;
|
2009-03-22 11:12:11 -04:00
|
|
|
|
|
|
|
case CELL_TYPE_ERROR:
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
throw new RuntimeException("Unexpected cell type (" + cellType + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
private String convertCellValueToString() {
|
|
|
|
int cellType = getCellType();
|
|
|
|
|
|
|
|
switch (cellType) {
|
|
|
|
case CELL_TYPE_BLANK:
|
|
|
|
return "";
|
|
|
|
case CELL_TYPE_BOOLEAN:
|
2009-08-18 12:50:24 -04:00
|
|
|
return TRUE_AS_STRING.equals(_cell.getV()) ? "TRUE" : "FALSE";
|
2009-03-22 11:12:11 -04:00
|
|
|
case CELL_TYPE_STRING:
|
2009-08-18 12:50:24 -04:00
|
|
|
int sstIndex = Integer.parseInt(_cell.getV());
|
|
|
|
XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex));
|
2009-03-22 11:12:11 -04:00
|
|
|
return rt.getString();
|
|
|
|
case CELL_TYPE_NUMERIC:
|
2009-08-18 12:50:24 -04:00
|
|
|
return String.valueOf(Double.parseDouble(_cell.getV()));
|
2009-03-22 11:12:11 -04:00
|
|
|
case CELL_TYPE_ERROR:
|
2009-08-18 12:50:24 -04:00
|
|
|
return _cell.getV();
|
2009-03-22 11:12:11 -04:00
|
|
|
case CELL_TYPE_FORMULA:
|
|
|
|
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
throw new RuntimeException("Unexpected cell type (" + cellType + ")");
|
|
|
|
}
|
|
|
|
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|