You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2021/11/02 13:18:50 UTC
svn commit: r1894680 - in /poi/trunk/poi-ooxml/src:
main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java
Author: centic
Date: Tue Nov 2 13:18:50 2021
New Revision: 1894680
URL: http://svn.apache.org/viewvc?rev=1894680&view=rev
Log:
Check and fix issue when sheets are added while an existing workbook-evaluator is used.
Added:
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
Modified: poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java?rev=1894680&r1=1894679&r2=1894680&view=diff
==============================================================================
--- poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java (original)
+++ poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java Tue Nov 2 13:18:50 2021
@@ -17,6 +17,9 @@
package org.apache.poi.xssf.usermodel;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.FormulaParser;
@@ -29,8 +32,8 @@ import org.apache.poi.util.Internal;
*/
@Internal
public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
- private XSSFEvaluationSheet[] _sheetCache;
-
+ private final Map<XSSFSheet, XSSFEvaluationSheet> _sheetCache = new HashMap<>();
+
public static XSSFEvaluationWorkbook create(XSSFWorkbook book) {
if (book == null) {
return null;
@@ -48,9 +51,9 @@ public final class XSSFEvaluationWorkboo
@Override
public void clearAllCachedResultValues() {
super.clearAllCachedResultValues();
- _sheetCache = null;
+ _sheetCache.clear();
}
-
+
@Override
public int getSheetIndex(EvaluationSheet evalSheet) {
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
@@ -59,25 +62,22 @@ public final class XSSFEvaluationWorkboo
@Override
public EvaluationSheet getSheet(int sheetIndex) {
- // Performance optimization: build sheet cache the first time this is called
- // to avoid re-creating the XSSFEvaluationSheet each time a new cell is evaluated
+ // verify index and let the method in _uBook throw the exception so we report
+ // it the same way as in other places
+ if (sheetIndex < 0 || sheetIndex >= _uBook.getNumberOfSheets()) {
+ // this will throw an exception now as the index is out of bounds
+ _uBook.getSheetAt(sheetIndex);
+ }
+
+ // Performance optimization: build sheet cache for each sheet to avoid re-creating
+ // the XSSFEvaluationSheet each time a new cell is evaluated
// EvaluationWorkbooks make not guarantee to synchronize changes made to
// the underlying workbook after the EvaluationWorkbook is created.
- if (_sheetCache == null) {
- final int numberOfSheets = _uBook.getNumberOfSheets();
- _sheetCache = new XSSFEvaluationSheet[numberOfSheets];
- for (int i=0; i < numberOfSheets; i++) {
- _sheetCache[i] = new XSSFEvaluationSheet(_uBook.getSheetAt(i));
- }
- }
- if (sheetIndex < 0 || sheetIndex >= _sheetCache.length) {
- // do this to reuse the out-of-bounds logic and message from XSSFWorkbook
- _uBook.getSheetAt(sheetIndex);
- }
- return _sheetCache[sheetIndex];
+ final XSSFSheet sheet = _uBook.getSheetAt(sheetIndex);
+ return _sheetCache.computeIfAbsent(sheet, rows -> new XSSFEvaluationSheet(sheet));
}
- @Override
+ @Override
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
final XSSFCell cell = ((XSSFEvaluationCell)evalCell).getXSSFCell();
final int sheetIndex = _uBook.getSheetIndex(cell.getSheet());
Added: poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java?rev=1894680&view=auto
==============================================================================
--- poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java (added)
+++ poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFEvaluationWorkbook.java Tue Nov 2 13:18:50 2021
@@ -0,0 +1,80 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xssf.usermodel;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+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.CellRangeAddress;
+import org.junit.jupiter.api.Test;
+
+class TestXSSFEvaluationWorkbook {
+
+ @Test
+ void testRefToBlankCellInArrayFormula() {
+ Workbook wb = new XSSFWorkbook();
+
+ FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+ verifySheet(wb, formulaEvaluator);
+
+ verifySheet(wb, formulaEvaluator);
+
+ wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+ }
+
+ private void verifySheet(Workbook wb, FormulaEvaluator formulaEvaluator) {
+ Sheet sheet = wb.createSheet();
+ Row row = sheet.createRow(0);
+ Cell cellA1 = row.createCell(0);
+ Cell cellB1 = row.createCell(1);
+ Cell cellC1 = row.createCell(2);
+ Row row2 = sheet.createRow(1);
+ Cell cellA2 = row2.createCell(0);
+ Cell cellB2 = row2.createCell(1);
+ Cell cellC2 = row2.createCell(2);
+ Row row3 = sheet.createRow(2);
+ Cell cellA3 = row3.createCell(0);
+ Cell cellB3 = row3.createCell(1);
+ Cell cellC3 = row3.createCell(2);
+
+ cellA1.setCellValue("1");
+ // cell B1 intentionally left blank
+ cellC1.setCellValue("3");
+
+ cellA2.setCellFormula("A1");
+ cellB2.setCellFormula("B1");
+ cellC2.setCellFormula("C1");
+
+ sheet.setArrayFormula("A1:C1", CellRangeAddress.valueOf("A3:C3"));
+
+ formulaEvaluator.evaluateAll();
+
+ assertEquals("1", cellA2.getStringCellValue());
+ assertEquals(0,cellB2.getNumericCellValue(), 0.00001);
+ assertEquals("3",cellC2.getStringCellValue());
+
+ assertEquals("1", cellA3.getStringCellValue());
+ assertEquals(0,cellB3.getNumericCellValue(), 0.00001);
+ assertEquals("3",cellC3.getStringCellValue());
+ }
+
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org