]> source.dussan.org Git - poi.git/commitdiff
Bugzilla 51790: fixed reading shared formulas in XSSF
authorYegor Kozlov <yegor@apache.org>
Mon, 27 Feb 2012 12:18:45 +0000 (12:18 +0000)
committerYegor Kozlov <yegor@apache.org>
Mon, 27 Feb 2012 12:18:45 +0000 (12:18 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1294127 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
test-data/spreadsheet/51790.xlsx [new file with mode: 0644]

index bd83e48d600308b766f3cd4900f95b33619180fb..cbd39ea9debfcf93d5678601c379e532204f561a 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta6" date="2012-??-??">
+           <action dev="poi-developers" type="add">51710 - fixed reading shared formulas in XSSF </action>
            <action dev="poi-developers" type="add">52708 - misc improvements in CellFormat </action>
            <action dev="poi-developers" type="add">52690 - added a getter for length of encrypted data in Ecma and Agile decryptors</action>
            <action dev="poi-developers" type="fix">52255 - support adding TIFF,EPS and WPG pictures in OOXML documents </action>
index fa7ce429d82e00e41e4137ccfe5c6b3680b3fe1d..2d0566a3d339571e587bd3e9157708bd375e4b89 100644 (file)
@@ -2670,7 +2670,20 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         if (f != null && f.getT() == STCellFormulaType.SHARED && f.isSetRef() && f.getStringValue() != null) {
             // save a detached  copy to avoid XmlValueDisconnectedException,
             // this may happen when the master cell of a shared formula is changed
-            sharedFormulas.put((int)f.getSi(), (CTCellFormula)f.copy());
+            CTCellFormula sf = (CTCellFormula)f.copy();
+            CellRangeAddress sfRef = CellRangeAddress.valueOf(sf.getRef());
+            CellReference cellRef = new CellReference(cell);
+            // If the shared formula range preceeds the master cell then the preseeing part is discarded, e.g.
+            // if the cell is E60 and the shared formula range is C60:M85 then the effective range is E60:M85
+            // see more details in https://issues.apache.org/bugzilla/show_bug.cgi?id=51710
+            if(cellRef.getCol() > sfRef.getFirstColumn() || cellRef.getRow() > sfRef.getFirstRow()){
+                String effectiveRef = new CellRangeAddress(
+                        Math.max(cellRef.getRow(), sfRef.getFirstRow()), sfRef.getLastRow(),
+                        Math.max(cellRef.getCol(), sfRef.getFirstColumn()), sfRef.getLastColumn()).formatAsString();
+                sf.setRef(effectiveRef);
+            }
+
+            sharedFormulas.put((int)f.getSi(), sf);
         }
         if (f != null && f.getT() == STCellFormulaType.ARRAY && f.getRef() != null) {
             arrayFormulas.add(CellRangeAddress.valueOf(f.getRef()));
index 0a781748f99091dfb30672f35a4630b3202494d4..b7a90c1a963d8983ec400594ba80b0811cb66210 100644 (file)
@@ -44,6 +44,7 @@ import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.CalculationChain;
@@ -1285,4 +1286,35 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
        assertEquals(20.0, c1.getNumericCellValue());
        assertEquals(20.0, c2.getNumericCellValue());
     }
+
+    /**
+     * Bugzilla 51710: problems reading shared formuals from .xlsx
+     */
+    public void test51710() {
+        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51790.xlsx");
+
+        final String[] columns = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N"};
+        final int rowMax = 500; // bug triggers on row index 59
+
+        Sheet sheet = wb.getSheetAt(0);
+
+
+        // go through all formula cells
+        for (int rInd = 2; rInd <= rowMax; rInd++) {
+            Row row = sheet.getRow(rInd);
+
+            for (int cInd = 1; cInd <= 12; cInd++) {
+                Cell cell = row.getCell(cInd);
+                String formula = cell.getCellFormula();
+                CellReference ref = new CellReference(cell);
+
+                //simulate correct answer
+                String correct = "$A" + (rInd + 1) + "*" + columns[cInd] + "$2";
+
+                assertEquals("Incorrect formula in " + ref.formatAsString(), correct, formula);
+            }
+
+        }
+    }
+
 }
diff --git a/test-data/spreadsheet/51790.xlsx b/test-data/spreadsheet/51790.xlsx
new file mode 100644 (file)
index 0000000..772395b
Binary files /dev/null and b/test-data/spreadsheet/51790.xlsx differ