2019-01-07 19:10:19 +00: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.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 {
|
2019-01-26 10:09:13 +00:00
|
|
|
// todo validate formula here, before changing the cell?
|
|
|
|
|
tryToDeleteArrayFormulaIfSet();
|
|
|
|
|
|
2019-01-07 19:10:19 +00:00
|
|
|
if (formula == null) {
|
|
|
|
|
removeFormula();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-26 10:09:13 +00:00
|
|
|
// formula cells always have a value. If the cell is blank (either initially or after removing an
|
|
|
|
|
// array formula), set value to 0
|
|
|
|
|
if (getValueType() == CellType.BLANK) {
|
2019-01-07 19:10:19 +00:00
|
|
|
setCellValue(0);
|
|
|
|
|
}
|
2019-01-26 10:09:13 +00:00
|
|
|
|
|
|
|
|
setCellFormulaImpl(formula);
|
2019-01-07 19:10:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-01-26 10:09:13 +00:00
|
|
|
* Implementation-specific setting the formula. Formula is not null.
|
2019-01-07 19:10:19 +00:00
|
|
|
* Shall not change the value.
|
|
|
|
|
* @param formula
|
|
|
|
|
*/
|
|
|
|
|
protected abstract void setCellFormulaImpl(String formula);
|
|
|
|
|
|
2019-01-26 10:09:13 +00:00
|
|
|
/**
|
|
|
|
|
* Get value type of this cell. Can return BLANK, NUMERIC, STRING, BOOLEAN or ERROR.
|
|
|
|
|
* For current implementations where type is strongly coupled with formula, is equivalent to
|
|
|
|
|
* <code>getCellType() == CellType.FORMULA ? getCachedFormulaResultType() : getCellType()</code>
|
|
|
|
|
*
|
|
|
|
|
* <p>This is meant as a temporary helper method until the time when value type is decoupled from the formula.</p>
|
|
|
|
|
* @return value type
|
|
|
|
|
*/
|
|
|
|
|
protected final CellType getValueType() {
|
|
|
|
|
CellType type = getCellType();
|
|
|
|
|
if (type != CellType.FORMULA) {
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
return getCachedFormulaResultType();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 19:10:19 +00:00
|
|
|
/**
|
|
|
|
|
* {@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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|