mirror of https://github.com/apache/poi.git
Check and fix issue when sheets are added while an existing workbook-evaluator is used.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894680 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
da930c4f87
commit
34ea6a50e0
|
@ -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 XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
|
|||
@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 XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
|
|||
|
||||
@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());
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue