]> source.dussan.org Git - poi.git/commitdiff
[bug-65464] fix issue where shared formulas can be corrupted
authorPJ Fanning <fanningpj@apache.org>
Wed, 28 Jul 2021 09:36:37 +0000 (09:36 +0000)
committerPJ Fanning <fanningpj@apache.org>
Wed, 28 Jul 2021 09:36:37 +0000 (09:36 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1891849 13f79535-47bb-0310-9956-ffa450edef68

poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
test-data/spreadsheet/bug65464.xlsx [new file with mode: 0644]

index 3ff4fc70e45c15120f7c1335ab9870828206eacb..a631b5f22b43dc55668ed92ff1ceb633b862e8bd 100644 (file)
@@ -4619,18 +4619,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet  {
                 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 && nextCell.getCellType() == CellType.FORMULA){
-                            CTCellFormula nextF = nextCell.getCTCell().getF();
-                            nextF.setStringValue(nextCell.getCellFormula(evalWb));
-                            CellRangeAddress nextRef = new CellRangeAddress(
-                                    nextCell.getRowIndex(), ref.getLastRow(),
-                                    nextCell.getColumnIndex(), ref.getLastColumn());
-                            nextF.setRef(nextRef.formatAsString());
-
-                            sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF);
-                            break DONE;
+                    if(row != null) {
+                        for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){
+                            XSSFCell nextCell = row.getCell(j);
+                            if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA) {
+                                CTCellFormula nextF = nextCell.getCTCell().getF();
+                                nextF.setStringValue(nextCell.getCellFormula(evalWb));
+                                nextF.setT(STCellFormulaType.SHARED); //https://bz.apache.org/bugzilla/show_bug.cgi?id=65464
+                                CellRangeAddress nextRef = new CellRangeAddress(
+                                        nextCell.getRowIndex(), ref.getLastRow(),
+                                        nextCell.getColumnIndex(), ref.getLastColumn());
+                                nextF.setRef(nextRef.formatAsString());
+
+                                sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF);
+                                break DONE;
+                            }
                         }
                     }
                 }
index 450f02b7af172821bdca5665ffdd7efc524712c9..ea5803bc904a2d9d25303105211a889a0f5403bb 100644 (file)
@@ -117,13 +117,7 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.CsvSource;
 import org.junit.jupiter.params.provider.EnumSource;
 import org.junit.jupiter.params.provider.ValueSource;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXParseException;
@@ -3544,4 +3538,25 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
             assertEquals(HorizontalAlignment.LEFT, cellLeft.getCellStyle().getAlignment());
         }
     }
+
+    @Test
+    void test65464() throws IOException {
+        try (XSSFWorkbook wb = openSampleWorkbook("bug65464.xlsx")) {
+            XSSFSheet sheet = wb.getSheet("SheetWithSharedFormula");
+            XSSFCell v15 = sheet.getRow(14).getCell(21);
+            XSSFCell v16 = sheet.getRow(15).getCell(21);
+            assertEquals("U15/R15", v15.getCellFormula());
+            assertEquals(STCellFormulaType.SHARED, v15.getCTCell().getF().getT());
+            assertEquals("U16/R16", v16.getCellFormula());
+            assertEquals(STCellFormulaType.NORMAL, v16.getCTCell().getF().getT()); //anomaly in original file
+            int calcChainSize = wb.getCalculationChain().getCTCalcChain().sizeOfCArray();
+
+            v15.removeFormula();
+            assertEquals(CellType.NUMERIC, v15.getCellType(), "V15 is no longer a function");
+            assertNull(v15.getCTCell().getF(), "V15 xmlbeans function removed");
+            assertEquals("U16/R16", v16.getCellFormula());
+            assertEquals(STCellFormulaType.SHARED, v16.getCTCell().getF().getT());
+            assertEquals(calcChainSize - 1, wb.getCalculationChain().getCTCalcChain().sizeOfCArray());
+        }
+    }
 }
diff --git a/test-data/spreadsheet/bug65464.xlsx b/test-data/spreadsheet/bug65464.xlsx
new file mode 100644 (file)
index 0000000..48eccea
Binary files /dev/null and b/test-data/spreadsheet/bug65464.xlsx differ