From: Yegor Kozlov Date: Sat, 30 Dec 2017 16:34:57 +0000 (+0000) Subject: Bug 58106: when a cell with a 'master' shared formula is removed, the next cell... X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ca7549131bc84a57e1632d58eb25ff8475cba8b1;p=poi.git Bug 58106: when a cell with a 'master' shared formula is removed, the next cell in the range becomes the master git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1819623 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index 941e03711c..27c8dd5bb2 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -559,6 +559,7 @@ public final class XSSFCell implements Cell { if (formula == null) { wb.onDeleteFormula(this); if (_cell.isSetF()) { + _row.getSheet().onDeleteFormula(this); _cell.unsetF(); } return; @@ -963,6 +964,9 @@ public final class XSSFCell implements Cell { notifyArrayFormulaChanging(); } if(prevType == CellType.FORMULA && cellType != CellType.FORMULA) { + if (_cell.isSetF()) { + _row.getSheet().onDeleteFormula(this); + } getSheet().getWorkbook().onDeleteFormula(this); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 8ca7d2b1ef..8c81736952 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -4455,7 +4455,40 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { removeRelation(part.getDocumentPart(), true); } } - + + /** + * when a cell with a 'master' shared formula is removed, the next cell in the range becomes the master + */ + protected void onDeleteFormula(XSSFCell cell){ + + CTCellFormula f = cell.getCTCell().getF(); + if (f != null && f.getT() == STCellFormulaType.SHARED && f.isSetRef() && f.getStringValue() != null) { + + CellRangeAddress ref = CellRangeAddress.valueOf(f.getRef()); + if(ref.getNumberOfCells() > 1){ + DONE: + for(int i = cell.getRowIndex(); i <= ref.getLastRow(); i++){ + XSSFRow row = getRow(i); + if(row != null) for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){ + XSSFCell nextCell = row.getCell(j); + if(nextCell != null && nextCell != cell){ + CTCellFormula nextF = nextCell.getCTCell().getF(); + nextF.setStringValue(nextCell.getCellFormula()); + CellRangeAddress nextRef = new CellRangeAddress( + nextCell.getRowIndex(), ref.getLastRow(), + nextCell.getColumnIndex(), ref.getLastColumn()); + nextF.setRef(nextRef.formatAsString()); + + sharedFormulas.put((int)nextF.getSi(), nextF); + break DONE; + } + } + } + } + + } + } + /** * Determine the OleObject which links shapes with embedded resources * diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java index 0735456e5c..d69ab95cfb 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java @@ -48,6 +48,7 @@ import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.model.SharedStringsTable; import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; @@ -701,4 +702,47 @@ public final class TestXSSFCell extends BaseTestXCell { } } + + @Test + public void testBug58106RemoveSharedFormula() throws Exception { + try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("58106.xlsx")) { + XSSFSheet sheet = wb.getSheetAt(0); + XSSFRow row = sheet.getRow(12); + XSSFCell cell = row.getCell(1); + CTCellFormula f = cell.getCTCell().getF(); + assertEquals("B13:G13", f.getRef()); + assertEquals("SUM(B1:B3)", f.getStringValue()); + assertEquals(0, f.getSi()); + assertEquals(STCellFormulaType.SHARED, f.getT()); + for(char i = 'C'; i <= 'G'; i++){ + XSSFCell sc =row.getCell(i-'A'); + CTCellFormula sf = sc.getCTCell().getF(); + assertFalse(sf.isSetRef()); + assertEquals("", sf.getStringValue()); + assertEquals(0, sf.getSi()); + assertEquals(STCellFormulaType.SHARED, sf.getT()); + } + assertEquals("B13:G13", sheet.getSharedFormula(0).getRef()); + + cell.setCellType(CellType.NUMERIC); + + assertFalse(cell.getCTCell().isSetF()); + + XSSFCell nextFormulaMaster = row.getCell(2); + assertEquals("C13:G13", nextFormulaMaster.getCTCell().getF().getRef()); + assertEquals("SUM(C1:C3)", nextFormulaMaster.getCTCell().getF().getStringValue()); + assertEquals(0, nextFormulaMaster.getCTCell().getF().getSi()); + for(char i = 'D'; i <= 'G'; i++){ + XSSFCell sc =row.getCell(i-'A'); + CTCellFormula sf = sc.getCTCell().getF(); + assertFalse(sf.isSetRef()); + assertEquals("", sf.getStringValue()); + assertEquals(0, sf.getSi()); + assertEquals(STCellFormulaType.SHARED, sf.getT()); + } + assertEquals("C13:G13", sheet.getSharedFormula(0).getRef()); + + } + + } } \ No newline at end of file diff --git a/test-data/spreadsheet/58106.xlsx b/test-data/spreadsheet/58106.xlsx new file mode 100644 index 0000000000..805d698eb9 Binary files /dev/null and b/test-data/spreadsheet/58106.xlsx differ