Author: gallon
Date: Mon Jan 7 19:10:19 2019
New Revision: 1850676
URL: http://svn.apache.org/viewvc?rev=1850676&view=rev
Log:
unified setCellType(null/_NONE) logic, setCellFormula(null) logic. updated
javadoc and tests
Added:
poi/trunk/src/java/org/apache/poi/ss/usermodel/CellBase.java
Modified:
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
poi/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java
poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java Mon Jan 7
19:10:19 2019
@@ -43,6 +43,7 @@ import org.apache.poi.ss.formula.eval.Er
import org.apache.poi.ss.formula.ptg.ExpPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellBase;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Comment;
@@ -68,7 +69,7 @@ import org.apache.poi.util.Removal;
* cells that have values should be added.
* <p>
*/
-public class HSSFCell implements Cell {
+public class HSSFCell extends CellBase {
private static final String FILE_FORMAT_NAME = "BIFF8";
/**
* The maximum number of columns in BIFF8
@@ -255,17 +256,10 @@ public class HSSFCell implements Cell {
return new CellAddress(this);
}
- /**
- * Set the cells type (numeric, formula or string).
- * If the cell currently contains a value, the value will
- * be converted to match the new type, if possible.
- */
@Override
- public void setCellType(CellType cellType) {
+ protected void setCellTypeImpl(CellType cellType) {
notifyFormulaChanging();
- if(isPartOfArrayFormulaGroup()){
- notifyArrayFormulaChanging();
- }
+
int row=_record.getRow();
short col=_record.getColumn();
short styleIndex=_record.getXFIndex();
@@ -594,26 +588,21 @@ public class HSSFCell implements Cell {
_stringValue.setUnicodeString(_book.getWorkbook().getSSTString(index));
}
- public void setCellFormula(String formula) {
- if(isPartOfArrayFormulaGroup()){
- notifyArrayFormulaChanging();
- }
+ @Override
+ protected void setCellFormulaImpl(String formula) {
+ assert formula != null;
int row=_record.getRow();
short col=_record.getColumn();
short styleIndex=_record.getXFIndex();
- if (formula==null) {
- notifyFormulaChanging();
- setCellType(CellType.BLANK, false, row, col, styleIndex);
- return;
- }
int sheetIndex = _book.getSheetIndex(_sheet);
Ptg[] ptgs = HSSFFormulaParser.parse(formula, _book, FormulaType.CELL,
sheetIndex);
setCellType(CellType.FORMULA, false, row, col, styleIndex);
FormulaRecordAggregate agg = (FormulaRecordAggregate) _record;
FormulaRecord frec = agg.getFormulaRecord();
frec.setOptions((short) 2);
+
frec.setValue(0);
//only set to default if there is no extended format index already set
@@ -622,6 +611,42 @@ public class HSSFCell implements Cell {
}
agg.setParsedExpression(ptgs);
}
+
+ @Override
+ protected void removeFormulaImpl() {
+ assert getCellType() == CellType.FORMULA;
+
+ notifyFormulaChanging();
+
+ switch (getCachedFormulaResultType()) {
+ case NUMERIC:
+ double numericValue =
((FormulaRecordAggregate)_record).getFormulaRecord().getValue();
+ _record = new NumberRecord();
+ ((NumberRecord)_record).setValue(numericValue);
+ _cellType = CellType.NUMERIC;
+ break;
+ case STRING:
+ _record = new NumberRecord();
+ ((NumberRecord)_record).setValue(0);
+ _cellType = CellType.STRING;
+ break;
+ case BOOLEAN:
+ boolean booleanValue =
((FormulaRecordAggregate)_record).getFormulaRecord().getCachedBooleanValue();
+ _record = new BoolErrRecord();
+ ((BoolErrRecord)_record).setValue(booleanValue);
+ _cellType = CellType.BOOLEAN;
+ break;
+ case ERROR:
+ byte errorValue = (byte)
((FormulaRecordAggregate)_record).getFormulaRecord().getCachedErrorValue();
+ _record = new BoolErrRecord();
+ ((BoolErrRecord)_record).setValue(errorValue);
+ _cellType = CellType.ERROR;
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+
/**
* Should be called any time that a formula could potentially be deleted.
* Does nothing if this cell currently does not hold a formula
@@ -1193,40 +1218,6 @@ public class HSSFCell implements Cell {
}
/**
- * The purpose of this method is to validate the cell state prior to
modification
- *
- * @see #notifyArrayFormulaChanging()
- */
- void notifyArrayFormulaChanging(String msg){
- CellRangeAddress cra = getArrayFormulaRange();
- if(cra.getNumberOfCells() > 1) {
- throw new IllegalStateException(msg);
- }
- //un-register the single-cell array formula from the parent XSSFSheet
- getRow().getSheet().removeArrayFormula(this);
- }
-
- /**
- * Called when this cell is modified.
- * <p>
- * The purpose of this method is to validate the cell state prior to
modification.
- * </p>
- *
- * @see #setCellFormula(String)
- * @see HSSFRow#removeCell(org.apache.poi.ss.usermodel.Cell)
- * @see
org.apache.poi.hssf.usermodel.HSSFSheet#removeRow(org.apache.poi.ss.usermodel.Row)
- * @see org.apache.poi.hssf.usermodel.HSSFSheet#shiftRows(int, int, int)
- * @see
org.apache.poi.hssf.usermodel.HSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)
- * @throws IllegalStateException if modification is not allowed
- */
- void notifyArrayFormulaChanging(){
- CellReference ref = new CellReference(this);
- String msg = "Cell "+ref.formatAsString()+" is part of a multi-cell
array formula. " +
- "You cannot change part of an array.";
- notifyArrayFormulaChanging(msg);
- }
-
- /**
* Applying a user-defined style (UDS) is special. Excel does not directly
reference user-defined styles, but
* instead create a 'proxy' ExtendedFormatRecord referencing the UDS as
parent.
*
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java Mon Jan 7
19:10:19 2019
@@ -164,7 +164,7 @@ public final class HSSFRow implements Ro
throw new RuntimeException("Specified cell is not from this row");
}
if(cell.isPartOfArrayFormulaGroup()){
- cell.notifyArrayFormulaChanging();
+ cell.tryToDeleteArrayFormula(null);
}
cells[column]=null;
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Mon Jan 7
19:10:19 2019
@@ -299,7 +299,7 @@ public final class HSSFSheet implements
HSSFCell xcell = (HSSFCell) cell;
if (xcell.isPartOfArrayFormulaGroup()) {
String msg = "Row[rownum=" + row.getRowNum() + "] contains
cell(s) included in a multi-cell array formula. You cannot change part of an
array.";
- xcell.notifyArrayFormulaChanging(msg);
+ xcell.tryToDeleteArrayFormula(msg);
}
}
@@ -1779,7 +1779,7 @@ public final class HSSFSheet implements
for (Cell cell : row) {
HSSFCell hcell = (HSSFCell) cell;
if (hcell.isPartOfArrayFormulaGroup()) {
- hcell.notifyArrayFormulaChanging(msg);
+ hcell.tryToDeleteArrayFormula(msg);
}
}
}
Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java Mon Jan 7
19:10:19 2019
@@ -70,17 +70,22 @@ public interface Cell {
Row getRow();
/**
- * Set the cells type (numeric, formula or string).
+ * Set the cells type (blank, numeric, boolean, error or string).
* <p>If the cell currently contains a value, the value will
* be converted to match the new type, if possible. Formatting
* is generally lost in the process however.</p>
+ * <p>Conversion rules:</p>
+ * <p>to NUMERIC: numeric value is left as is. True converts to 1.0, false
converts to 0. otherwise, the
+ * value is set to 0. Formula is removed.</p>
* <p>If what you want to do is get a String value for your
* numeric cell, <i>stop!</i>. This is not the way to do it.
* Instead, for fetching the string value of a numeric or boolean
- * or date cell, use {@link DataFormatter} instead.</p>
- *
- * @throws IllegalArgumentException if the specified cell type is invalid
- * @throws IllegalStateException if the current value cannot be converted
to the new type
+ * or date cell, use {@link DataFormatter} instead.</p>
+ * <p>If cell is a member of an array formula group containing more than 1
cell, an {@link IllegalStateException}
+ * is thrown. If the array formula group contains only this cell, it is
removed</p>
+ * @throws IllegalArgumentException if the specified cell type is invalid
(null or _NONE)
+ * @throws IllegalStateException if the current value cannot be converted
to the new type or
+ * if the cell is a part of an array formula group containing other cells
*/
void setCellType(CellType cellType);
@@ -90,7 +95,7 @@ public interface Cell {
* @return the cell type
*/
CellType getCellType();
-
+
/**
* Return the cell type.
*
@@ -101,13 +106,13 @@ public interface Cell {
@Deprecated
@Removal(version="4.2")
CellType getCellTypeEnum();
-
+
/**
* Only valid for formula cells
- *
+ *
* Will return {@link CellType} in a future version of POI.
* For forwards compatibility, do not hard-code cell type literals in your
code.
- *
+ *
* @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING},
* {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending
* on the cached value of the formula
@@ -138,7 +143,7 @@ public interface Cell {
/**
* <p>Converts the supplied date to its equivalent Excel numeric value and
sets
* that into the cell.</p>
- *
+ *
* <p><b>Note</b> - There is actually no 'DATE' cell type in Excel. In many
* cases (when entering date values), Excel automatically adjusts the
* <i>cell style</i> to some date format, creating the illusion that the
cell
@@ -193,16 +198,33 @@ public interface Cell {
/**
* Sets formula for this cell.
+ *
* <p>
* Note, this method only sets the formula string and does not calculate
the formula value.
- * To set the precalculated value use {@link #setCellValue(double)} or
{@link #setCellValue(String)}
+ * To set the precalculated value use {@link #setCellValue}
+ * </p>
+ *
+ * <p>
+ * If the cell was blank, sets value to 0. Otherwise, preserves the value
as precalculated.
* </p>
*
* @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>.
- * If the argument is <code>null</code> then the current formula is
removed.
+ * If the argument is <code>null</code> then the current formula is
removed.
+ *
+ * @throws IllegalStateException if this cell is a part of an array
formula group containing other cells
* @throws FormulaParseException if the formula has incorrect syntax or is
otherwise invalid
*/
- void setCellFormula(String formula) throws FormulaParseException;
+ void setCellFormula(String formula) throws FormulaParseException,
IllegalStateException;
+
+ /**
+ * Removes formula, if any.
+ *
+ * If cell was blank, leaves it as is.
+ * If it is a part of an array formula group, blanks the cell.
+ * If has a regular formula, removes the formula preserving the "cached"
value.
+ * @throws IllegalStateException if cell is a part of an array formula
group containing other cells
+ */
+ void removeFormula() throws IllegalStateException;
/**
* Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
@@ -304,7 +326,7 @@ public interface Cell {
/**
* <p>Set the style for the cell. The style should be an CellStyle
created/retrieved from
* the Workbook.</p>
- *
+ *
* <p>To change the style of a cell without affecting other cells that use
the same style,
* use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell,
Map)}</p>
*
Added: poi/trunk/src/java/org/apache/poi/ss/usermodel/CellBase.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/CellBase.java?rev=1850676&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/CellBase.java (added)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/CellBase.java Mon Jan 7
19:10:19 2019
@@ -0,0 +1,137 @@
+/* ====================================================================
+ 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.ss.formula.FormulaParseException;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+
+/**
+ * Common implementation-independent logic shared by all implementations of
{@link Cell}.
+ * @author Vladislav "gallon" Galas gallon at apache dot org
+ */
+public abstract class CellBase implements Cell {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void setCellType(CellType cellType) {
+ if (cellType == null || cellType == CellType._NONE) {
+ throw new IllegalArgumentException("cellType shall not be null nor
_NONE");
+ }
+
+ tryToDeleteArrayFormulaIfSet();
+
+ setCellTypeImpl(cellType);
+ }
+
+ /**
+ * Implementation-specific logic
+ * @param cellType new cell type. Guaranteed non-null, not _NONE.
+ */
+ protected abstract void setCellTypeImpl(CellType cellType);
+
+ /**
+ * Called when this an array formula in this cell is deleted.
+ * <p>The purpose of this method is to validate the cell state prior to
modification.</p>
+ *
+ * @param message a customized exception message for the case if deletion
of the cell is impossible. If null, a
+ * default message will be generated
+ * @see #setCellType(CellType)
+ * @see #setCellFormula(String)
+ * @see Row#removeCell(org.apache.poi.ss.usermodel.Cell)
+ * @see
org.apache.poi.ss.usermodel.Sheet#removeRow(org.apache.poi.ss.usermodel.Row)
+ * @see org.apache.poi.ss.usermodel.Sheet#shiftRows(int, int, int)
+ * @see
org.apache.poi.ss.usermodel.Sheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)
+ * @throws IllegalStateException if modification is not allowed
+ *
+ * Note. Exposing this to public is ugly. Needed for methods like
Sheet#shiftRows.
+ */
+ public final void tryToDeleteArrayFormula(String message) {
+ assert isPartOfArrayFormulaGroup();
+
+ CellRangeAddress arrayFormulaRange = getArrayFormulaRange();
+ if(arrayFormulaRange.getNumberOfCells() > 1) {
+ if (message == null) {
+ message = "Cell " + new CellReference(this).formatAsString() +
" is part of a multi-cell array formula. " +
+ "You cannot change part of an array.";
+ }
+ throw new IllegalStateException(message);
+ }
+ //un-register the single-cell array formula from the parent sheet
through public interface
+ getRow().getSheet().removeArrayFormula(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void setCellFormula(String formula) throws
FormulaParseException, IllegalStateException {
+ if (formula == null) {
+ removeFormula();
+ return;
+ }
+
+ CellType previousValueType = getCellType() == CellType.FORMULA ?
getCachedFormulaResultType() : getCellType();
+
+ tryToDeleteArrayFormulaIfSet();
+
+ setCellFormulaImpl(formula);
+
+ if (previousValueType == CellType.BLANK) {
+ setCellValue(0);
+ }
+ }
+
+ /**
+ * Implementation-specific setting the formula.
+ * Shall not change the value.
+ * @param formula
+ */
+ protected abstract void setCellFormulaImpl(String formula);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void removeFormula() {
+ if (getCellType() == CellType.BLANK) {
+ return;
+ }
+
+ if (isPartOfArrayFormulaGroup()) {
+ tryToDeleteArrayFormula(null);
+ return;
+ }
+
+ removeFormulaImpl();
+ }
+
+ /**
+ * Implementation-specific removal of the formula.
+ * The cell is guaranteed to have a regular formula set.
+ * Shall preserve the "cached" value.
+ */
+ protected abstract void removeFormulaImpl();
+
+ private void tryToDeleteArrayFormulaIfSet() {
+ if (isPartOfArrayFormulaGroup()) {
+ tryToDeleteArrayFormula(null);
+ }
+ }
+}
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
(original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java Mon
Jan 7 19:10:19 2019
@@ -27,6 +27,7 @@ import org.apache.poi.ss.SpreadsheetVers
import org.apache.poi.ss.formula.FormulaParseException;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellBase;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Comment;
@@ -45,7 +46,7 @@ import org.apache.poi.xssf.usermodel.XSS
/**
* Streaming version of XSSFCell implementing the "BigGridDemo" strategy.
*/
-public class SXSSFCell implements Cell {
+public class SXSSFCell extends CellBase {
private final SXSSFRow _row;
private Value _value;
private CellStyle _style;
@@ -111,14 +112,8 @@ public class SXSSFCell implements Cell {
return _row;
}
- /**
- * Set the cells type (numeric, formula or string)
- *
- * @throws IllegalArgumentException if the specified cell type is invalid
- */
@Override
- public void setCellType(CellType cellType)
- {
+ protected void setCellTypeImpl(CellType cellType) {
ensureType(cellType);
}
@@ -331,7 +326,7 @@ public class SXSSFCell implements Cell {
* @throws FormulaParseException if the formula has incorrect syntax or is
otherwise invalid
*/
@Override
- public void setCellFormula(String formula) throws FormulaParseException
+ public void setCellFormulaImpl(String formula) throws FormulaParseException
{
if(formula == null) {
setType(CellType.BLANK);
@@ -341,6 +336,36 @@ public class SXSSFCell implements Cell {
ensureFormulaType(computeTypeFromFormula(formula));
((FormulaValue)_value).setValue(formula);
}
+
+ @Override
+ protected void removeFormulaImpl() {
+ assert getCellType() == CellType.FORMULA;
+ switch (getCachedFormulaResultType()) {
+ case NUMERIC:
+ double numericValue =
((NumericFormulaValue)_value).getPreEvaluatedValue();
+ _value = new NumericValue();
+ ((NumericValue) _value).setValue(numericValue);
+ break;
+ case STRING:
+ String stringValue =
((StringFormulaValue)_value).getPreEvaluatedValue();
+ _value = new PlainStringValue();
+ ((PlainStringValue) _value).setValue(stringValue);
+ break;
+ case BOOLEAN:
+ boolean booleanValue =
((BooleanFormulaValue)_value).getPreEvaluatedValue();
+ _value = new BooleanValue();
+ ((BooleanValue) _value).setValue(booleanValue);
+ break;
+ case ERROR:
+ byte errorValue =
((ErrorFormulaValue)_value).getPreEvaluatedValue();
+ _value = new ErrorValue();
+ ((ErrorValue) _value).setValue(errorValue);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+
/**
* Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
*
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
(original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java Mon
Jan 7 19:10:19 2019
@@ -30,6 +30,7 @@ import org.apache.poi.ss.formula.SharedF
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellBase;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
@@ -70,7 +71,7 @@ import org.openxmlformats.schemas.spread
* cells that have values should be added.
* </p>
*/
-public final class XSSFCell implements Cell {
+public final class XSSFCell extends CellBase {
private static final String FALSE_AS_STRING = "0";
private static final String TRUE_AS_STRING = "1";
@@ -549,10 +550,7 @@ public final class XSSFCell implements C
* when the cell is a part of a multi-cell array formula
*/
@Override
- public void setCellFormula(String formula) {
- if(isPartOfArrayFormulaGroup()){
- notifyArrayFormulaChanging();
- }
+ protected void setCellFormulaImpl(String formula) {
setFormula(formula, FormulaType.CELL);
}
@@ -565,7 +563,7 @@ public final class XSSFCell implements C
private void setFormula(String formula, FormulaType formulaType) {
XSSFWorkbook wb = _row.getSheet().getWorkbook();
- if (formula == null) {
+ if (formulaType == FormulaType.ARRAY && formula == null) {
wb.onDeleteFormula(this);
if (_cell.isSetF()) {
_row.getSheet().onDeleteFormula(this, null);
@@ -597,6 +595,15 @@ public final class XSSFCell implements C
}
}
+ @Override
+ protected void removeFormulaImpl() {
+ _row.getSheet().getWorkbook().onDeleteFormula(this);
+ if (_cell.isSetF()) {
+ _row.getSheet().onDeleteFormula(this, null);
+ _cell.unsetF();
+ }
+ }
+
/**
* Returns column index of this cell
*
@@ -960,13 +967,8 @@ public final class XSSFCell implements C
_cell.setR(ref);
}
- /**
- * Set the cells type (numeric, formula or string)
- *
- * @throws IllegalArgumentException if the specified cell type is invalid
- */
@Override
- public void setCellType(CellType cellType) {
+ protected void setCellTypeImpl(CellType cellType) {
setCellType(cellType, null);
}
@@ -978,10 +980,6 @@ public final class XSSFCell implements C
*/
protected void setCellType(CellType cellType, BaseXSSFEvaluationWorkbook
evalWb) {
CellType prevType = getCellType();
-
- if(isPartOfArrayFormulaGroup()){
- notifyArrayFormulaChanging();
- }
if(prevType == CellType.FORMULA && cellType != CellType.FORMULA) {
if (_cell.isSetF()) {
_row.getSheet().onDeleteFormula(this, evalWb);
@@ -1307,48 +1305,12 @@ public final class XSSFCell implements C
return getSheet().isCellInArrayFormulaContext(this);
}
- /**
- * The purpose of this method is to validate the cell state prior to
modification
- *
- * @see #notifyArrayFormulaChanging()
- */
- void notifyArrayFormulaChanging(String msg){
- if(isPartOfArrayFormulaGroup()){
- CellRangeAddress cra = getArrayFormulaRange();
- if(cra.getNumberOfCells() > 1) {
- throw new IllegalStateException(msg);
- }
- //un-register the single-cell array formula from the parent
XSSFSheet
- getRow().getSheet().removeArrayFormula(this);
+ //Moved from XSSFRow.shift(). Not sure what is purpose.
+ public void updateCellReferencesForShifting(String msg){
+ if(isPartOfArrayFormulaGroup()) {
+ tryToDeleteArrayFormula(msg);
}
- }
- /**
- * Called when this cell is modified.
- * <p>
- * The purpose of this method is to validate the cell state prior to
modification.
- * </p>
- *
- * @see #setCellType(CellType)
- * @see #setCellFormula(String)
- * @see XSSFRow#removeCell(org.apache.poi.ss.usermodel.Cell)
- * @see
org.apache.poi.xssf.usermodel.XSSFSheet#removeRow(org.apache.poi.ss.usermodel.Row)
- * @see org.apache.poi.xssf.usermodel.XSSFSheet#shiftRows(int, int, int)
- * @see
org.apache.poi.xssf.usermodel.XSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)
- * @throws IllegalStateException if modification is not allowed
- */
- void notifyArrayFormulaChanging(){
- CellReference ref = new CellReference(this);
- String msg = "Cell "+ref.formatAsString()+" is part of a multi-cell
array formula. " +
- "You cannot change part of an array.";
- notifyArrayFormulaChanging(msg);
- }
-
-
- //Moved from XSSFRow.shift(). Not sure what is purpose.
- public void updateCellReferencesForShifting(String msg){
- if(isPartOfArrayFormulaGroup())
- notifyArrayFormulaChanging(msg);
CalculationChain calcChain =
getSheet().getWorkbook().getCalculationChain();
int sheetId = (int)getSheet().sheet.getSheetId();
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
(original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java Mon Jan
7 19:10:19 2019
@@ -480,7 +480,7 @@ public class XSSFRow implements Row, Com
XSSFCell xcell = (XSSFCell)cell;
if(xcell.isPartOfArrayFormulaGroup()) {
- xcell.notifyArrayFormulaChanging();
+ xcell.setCellFormula(null); // to remove the array formula
}
if(cell.getCellType() == CellType.FORMULA) {
_sheet.getWorkbook().onDeleteFormula(xcell);
Modified:
poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
---
poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java
(original)
+++
poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java
Mon Jan 7 19:10:19 2019
@@ -41,6 +41,7 @@ import org.apache.poi.xssf.usermodel.XSS
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlCursor;
import org.junit.AfterClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst;
@@ -146,4 +147,35 @@ public class TestSXSSFCell extends BaseT
byte result = cell.getErrorCellValue();
assertEquals(0, result);
}
+
+ /**
+ * For now, {@link SXSSFCell} doesn't support array formulas.
+ * However, this test should be enabled if array formulas are implemented
for SXSSF.
+ */
+ @Override
+ @Ignore
+ public void
setCellType_BLANK_removesArrayFormula_ifCellIsPartOfAnArrayFormulaGroupContainingOnlyThisCell()
{
+ }
+
+ /**
+ * For now, {@link SXSSFCell} doesn't support array formulas.
+ * However, this test should be enabled if array formulas are implemented
for SXSSF.
+ */
+ @Override
+ @Ignore
+ @Test // <- annotation is necessary to override expected exception
+ public void
setCellType_BLANK_throwsISE_ifCellIsPartOfAnArrayFormulaGroupContainingOtherCells()
{
+ }
+
+ @Override
+ @Ignore
+ @Test
+ public void
setCellFormula_throwsISE_ifCellIsPartOfAnArrayFormulaGroupContainingOtherCells()
{
+ }
+
+ @Override
+ @Ignore
+ @Test
+ public void
removeFormula_turnsCellToBlank_whenFormulaWasASingleCellArrayFormula() {
+ }
}
Modified: poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java?rev=1850676&r1=1850675&r2=1850676&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java Mon
Jan 7 19:10:19 2019
@@ -37,6 +37,7 @@ import org.apache.poi.common.usermodel.H
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.LocaleUtil;
import org.junit.Test;
@@ -1200,4 +1201,109 @@ public abstract class BaseTestCell {
assertEquals(CellType.NUMERIC, cell.getCellType());
assertEquals(value, cell.getNumericCellValue(), 0);
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void setCellType_null_throwsIAE() {
+ Cell cell = getInstance();
+ cell.setCellType(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void setCellType_NONE_throwsIAE() {
+ Cell cell = getInstance();
+ cell.setCellType(CellType._NONE);
+ }
+
+
+ @Test
+ public void
setCellType_BLANK_removesArrayFormula_ifCellIsPartOfAnArrayFormulaGroupContainingOnlyThisCell()
{
+ Cell cell = getInstance();
+
+ cell.getSheet().setArrayFormula("1", CellRangeAddress.valueOf("A1"));
+ cell.setCellValue("foo");
+ assertTrue(cell.isPartOfArrayFormulaGroup());
+ assertEquals("1", cell.getCellFormula());
+
+ cell.setCellType(CellType.BLANK);
+
+ assertEquals(CellType.BLANK, cell.getCellType());
+ assertFalse(cell.isPartOfArrayFormulaGroup());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void
setCellType_BLANK_throwsISE_ifCellIsPartOfAnArrayFormulaGroupContainingOtherCells()
{
+ Cell cell = getInstance();
+ cell.getSheet().setArrayFormula("1",
CellRangeAddress.valueOf("A1:B1"));
+ cell.setCellValue("foo");
+ cell.setCellType(CellType.BLANK);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void
setCellFormula_throwsISE_ifCellIsPartOfAnArrayFormulaGroupContainingOtherCells()
{
+ Cell cell = getInstance();
+
+ cell.getSheet().setArrayFormula("1",
CellRangeAddress.valueOf("A1:B1"));
+ assertTrue(cell.isPartOfArrayFormulaGroup());
+ assertEquals(CellType.FORMULA, cell.getCellType());
+
+ cell.setCellFormula("1");
+ }
+
+ @Test
+ public void removeFormula_preservesValue() {
+ Cell cell = getInstance();
+
+ cell.setCellFormula("#DIV/0!");
+ cell.setCellValue(true);
+ cell.removeFormula();
+ assertEquals(CellType.BOOLEAN, cell.getCellType());
+ assertTrue(cell.getBooleanCellValue());
+
+ cell.setCellFormula("#DIV/0!");
+ cell.setCellValue(2);
+ cell.removeFormula();
+ assertEquals(CellType.NUMERIC, cell.getCellType());
+ assertEquals(2, cell.getNumericCellValue(), 0);
+
+ cell.setCellFormula("#DIV/0!");
+ cell.setCellValue("foo");
+ cell.removeFormula();
+ assertEquals(CellType.STRING, cell.getCellType());
+ assertEquals("foo", cell.getStringCellValue());
+
+ cell.setCellFormula("#DIV/0!");
+ cell.setCellErrorValue(FormulaError.NUM.getCode());
+ cell.removeFormula();
+ assertEquals(CellType.ERROR, cell.getCellType());
+ assertEquals(FormulaError.NUM.getCode(), cell.getErrorCellValue());
+ }
+
+ @Test
+ public void
removeFormula_turnsCellToBlank_whenFormulaWasASingleCellArrayFormula() {
+ Cell cell = getInstance();
+
+ cell.getSheet().setArrayFormula("#DIV/0!",
CellRangeAddress.valueOf("A1"));
+ cell.setCellValue(true);
+ cell.removeFormula();
+ assertEquals(CellType.BLANK, cell.getCellType());
+
+ cell.getSheet().setArrayFormula("#DIV/0!",
CellRangeAddress.valueOf("A1"));
+ cell.setCellValue(2);
+ cell.removeFormula();
+ assertEquals(CellType.BLANK, cell.getCellType());
+
+ cell.getSheet().setArrayFormula("#DIV/0!",
CellRangeAddress.valueOf("A1"));
+ cell.setCellValue(true);
+ cell.removeFormula();
+ assertEquals(CellType.BLANK, cell.getCellType());
+
+ cell.getSheet().setArrayFormula("#DIV/0!",
CellRangeAddress.valueOf("A1"));
+ cell.setCellErrorValue(FormulaError.NUM.getCode());
+ cell.removeFormula();
+ assertEquals(CellType.BLANK, cell.getCellType());
+ }
+
+ private Cell getInstance() {
+ return
_testDataProvider.createWorkbook().createSheet().createRow(0).createCell(0);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]