]> source.dussan.org Git - poi.git/commitdiff
Bug 58106: when a cell with a 'master' shared formula is removed, the next cell...
authorYegor Kozlov <yegor@apache.org>
Sat, 30 Dec 2017 16:34:57 +0000 (16:34 +0000)
committerYegor Kozlov <yegor@apache.org>
Sat, 30 Dec 2017 16:34:57 +0000 (16:34 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1819623 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java
test-data/spreadsheet/58106.xlsx [new file with mode: 0644]

index 941e03711cce6ff0aaa4d2a1309010afa9f8b0e5..27c8dd5bb230731db0eb7953f2365c927c56f176 100644 (file)
@@ -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);
         }
 
index 8ca7d2b1efcc47d15134630988267c70a9387ac6..8c8173695250a43c03cc4a9f566c83e394ae45c3 100644 (file)
@@ -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
      *
index 0735456e5cdfcb8490043894435b8da3047ddc14..d69ab95cfb84e4ec07ae06ac0ace2c0c951df865 100644 (file)
@@ -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 (file)
index 0000000..805d698
Binary files /dev/null and b/test-data/spreadsheet/58106.xlsx differ