From: Yegor Kozlov Date: Mon, 27 Feb 2012 12:18:45 +0000 (+0000) Subject: Bugzilla 51790: fixed reading shared formulas in XSSF X-Git-Tag: REL_3_8_FINAL~28 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a6f40e2952bfaad335e670192b3b51a963c04d08;p=poi.git Bugzilla 51790: fixed reading shared formulas in XSSF git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1294127 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index bd83e48d60..cbd39ea9de 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 51710 - fixed reading shared formulas in XSSF 52708 - misc improvements in CellFormat 52690 - added a getter for length of encrypted data in Ecma and Agile decryptors 52255 - support adding TIFF,EPS and WPG pictures in OOXML documents 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 fa7ce429d8..2d0566a3d3 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -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())); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 0a781748f9..b7a90c1a96 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -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 index 0000000000..772395b4a9 Binary files /dev/null and b/test-data/spreadsheet/51790.xlsx differ