Fix bug #49966 - Correctly remove calcChain entries for XSSF cells that stop holding formulas

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@999314 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2010-09-21 11:16:12 +00:00
parent d3d674d250
commit 39a185e9a7
5 changed files with 50 additions and 4 deletions

View File

@ -34,6 +34,7 @@
<changes>
<release version="3.7-beta3" date="2010-??-??">
<action dev="poi-developers" type="fix">49966 - Correctly remove calcChain entries for XSSF cells that stop holding formulas</action>
<action dev="poi-developers" type="add">47582 - XSSFCellStyle support for creating a style in one workbook based on a style from a different one</action>
<action dev="poi-developers" type="fix">49931 - Avoid concurrency problems when re-ordering multiple HSSF header records for a PageSettingsBlock</action>
<action dev="poi-developers" type="fix">49765 - Fix XWPFDocument.addPicture so that it correctly sets up relationships</action>

View File

@ -721,11 +721,15 @@ public final class XSSFCell implements Cell {
* @see #CELL_TYPE_ERROR
*/
public void setCellType(int cellType) {
int prevType = getCellType();
if(isPartOfArrayFormulaGroup()){
notifyArrayFormulaChanging();
}
int prevType = getCellType();
if(prevType == CELL_TYPE_FORMULA && cellType != CELL_TYPE_FORMULA) {
getSheet().getWorkbook().onDeleteFormula(this);
}
switch (cellType) {
case CELL_TYPE_BLANK:
setBlank();

View File

@ -365,9 +365,12 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
}
XSSFCell xcell = (XSSFCell)cell;
if(xcell.isPartOfArrayFormulaGroup()){
if(xcell.isPartOfArrayFormulaGroup()) {
xcell.notifyArrayFormulaChanging();
}
if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
_sheet.getWorkbook().onDeleteFormula(xcell);
}
_cells.remove(cell.getColumnIndex());
}

View File

@ -833,7 +833,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
//delete the CTSheet reference from workbook.xml
workbook.getSheets().removeSheet(index);
//calculation chain is auxilary, remove it as it may contain orfan references to deleted cells
//calculation chain is auxiliary, remove it as it may contain orphan references to deleted cells
if(calcChain != null) {
removeRelation(calcChain);
calcChain = null;

View File

@ -38,6 +38,7 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
@ -544,4 +545,41 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
}
}
/**
* Various ways of removing a cell formula should all zap
* the calcChain entry.
*/
public void test49966() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("shared_formulas.xlsx");
XSSFSheet sheet = wb.getSheetAt(0);
// CalcChain has lots of entries
CalculationChain cc = wb.getCalculationChain();
assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
assertEquals("A3", cc.getCTCalcChain().getCArray(1).getR());
assertEquals("A4", cc.getCTCalcChain().getCArray(2).getR());
assertEquals("A5", cc.getCTCalcChain().getCArray(3).getR());
assertEquals("A6", cc.getCTCalcChain().getCArray(4).getR());
assertEquals("A7", cc.getCTCalcChain().getCArray(5).getR());
// Try various ways of changing the formulas
// If it stays a formula, chain entry should remain
// Otherwise should go
sheet.getRow(1).getCell(0).setCellFormula("A1"); // stay
sheet.getRow(2).getCell(0).setCellFormula(null); // go
sheet.getRow(3).getCell(0).setCellType(Cell.CELL_TYPE_FORMULA); // stay
sheet.getRow(4).getCell(0).setCellType(Cell.CELL_TYPE_STRING); // go
sheet.getRow(5).removeCell(
sheet.getRow(5).getCell(0) // go
);
// Save and check
wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
sheet = wb.getSheetAt(0);
cc = wb.getCalculationChain();
assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
assertEquals("A4", cc.getCTCalcChain().getCArray(1).getR());
assertEquals("A7", cc.getCTCalcChain().getCArray(2).getR());
}
}