#56132 Allow XSSF formula evaluation to also skip missing external workbook references, if requested

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1614729 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-07-30 18:08:28 +00:00
parent 1afa975f7f
commit a7df4f8b92
7 changed files with 90 additions and 26 deletions

View File

@ -378,21 +378,7 @@ public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluator
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
/**
* Whether to ignore missing references to external workbooks and
* use cached formula results in the main workbook instead.
* <p>
* In some cases exetrnal workbooks referenced by formulas in the main workbook are not avaiable.
* With this method you can control how POI handles such missing references:
* <ul>
* <li>by default ignoreMissingWorkbooks=false and POI throws {@link org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException}
* if an external reference cannot be resolved</li>
* <li>if ignoreMissingWorkbooks=true then POI uses cached formula result
* that already exists in the main workbook</li>
* </ul>
*
* @param ignore whether to ignore missing references to external workbooks
*/
/** {@inheritDoc} */
public void setIgnoreMissingWorkbooks(boolean ignore){
_bookEvaluator.setIgnoreMissingWorkbooks(ignore);
}

View File

@ -127,6 +127,24 @@ public interface FormulaEvaluator {
*/
void setupReferencedWorkbooks(Map<String,FormulaEvaluator> workbooks);
/**
* Whether to ignore missing references to external workbooks and
* use cached formula results in the main workbook instead.
* <p>
* In some cases external workbooks referenced by formulas in the main workbook are not available.
* With this method you can control how POI handles such missing references:
* <ul>
* <li>by default ignoreMissingWorkbooks=false and POI throws
* {@link org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException}
* if an external reference cannot be resolved</li>
* <li>if ignoreMissingWorkbooks=true then POI uses cached formula result
* that already exists in the main workbook</li>
* </ul>
*
* @param ignore whether to ignore missing references to external workbooks
*/
void setIgnoreMissingWorkbooks(boolean ignore);
/**
* Perform detailed output of formula evaluation for next evaluation only?
* Is for developer use only (also developers using POI for their XLS files).

View File

@ -73,13 +73,12 @@ public class SheetUtil {
public Cell evaluateInCell(Cell cell) { return null; }
public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> workbooks) {}
public void setDebugEvaluationOutputForNextEval(boolean value) {}
public void setIgnoreMissingWorkbooks(boolean ignore) {}
public void evaluateAll() {}
public int evaluateFormulaCell(Cell cell) {
return cell.getCachedFormulaResultType();
}
};
/**

View File

@ -44,6 +44,7 @@ public class ExternalLinksTable extends POIXMLDocumentPart {
public ExternalLinksTable() {
super();
link = CTExternalLink.Factory.newInstance();
link.addNewExternalBook();
}
public ExternalLinksTable(PackagePart part, PackageRelationship rel) throws IOException {

View File

@ -292,9 +292,13 @@ public class XSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluator
return _bookEvaluator;
}
/** {@inheritDoc} */
public void setIgnoreMissingWorkbooks(boolean ignore){
_bookEvaluator.setIgnoreMissingWorkbooks(ignore);
}
/** {@inheritDoc} */
public void setDebugEvaluationOutputForNextEval(boolean value){
_bookEvaluator.setDebugEvaluationOutputForNextEval(value);
}
}

View File

@ -0,0 +1,40 @@
/* ====================================================================
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 org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.formula.TestMissingWorkbook;
import org.apache.poi.xssf.XSSFTestDataSamples;
/**
* XSSF Specific version of the Missing Workbooks test
*/
public final class TestMissingWorkbookOnXSSF extends TestMissingWorkbook {
public TestMissingWorkbookOnXSSF() {
super("52575_main.xlsx", "source_dummy.xlsx", "52575_source.xls");
}
@Override
protected void setUp() throws Exception {
mainWorkbook = XSSFTestDataSamples.openSampleWorkbook(MAIN_WORKBOOK_FILENAME);
sourceWorkbook = HSSFTestDataSamples.openSampleWorkbook(SOURCE_WORKBOOK_FILENAME);
assertNotNull(mainWorkbook);
assertNotNull(sourceWorkbook);
}
}

View File

@ -33,12 +33,22 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class TestMissingWorkbook extends TestCase {
private static final String MAIN_WORKBOOK_FILENAME = "52575_main.xls";
private static final String SOURCE_DUMMY_WORKBOOK_FILENAME = "source_dummy.xls";
private static final String SOURCE_WORKBOOK_FILENAME = "52575_source.xls";
private Workbook mainWorkbook;
private Workbook sourceWorkbook;
protected Workbook mainWorkbook;
protected Workbook sourceWorkbook;
protected final String MAIN_WORKBOOK_FILENAME;
protected final String SOURCE_DUMMY_WORKBOOK_FILENAME;
protected final String SOURCE_WORKBOOK_FILENAME;
public TestMissingWorkbook() {
this("52575_main.xls", "source_dummy.xls", "52575_source.xls");
}
protected TestMissingWorkbook(String MAIN_WORKBOOK_FILENAME,
String SOURCE_DUMMY_WORKBOOK_FILENAME, String SOURCE_WORKBOOK_FILENAME) {
this.MAIN_WORKBOOK_FILENAME = MAIN_WORKBOOK_FILENAME;
this.SOURCE_DUMMY_WORKBOOK_FILENAME = SOURCE_DUMMY_WORKBOOK_FILENAME;
this.SOURCE_WORKBOOK_FILENAME = SOURCE_WORKBOOK_FILENAME;
}
@Override
protected void setUp() throws Exception {
@ -74,12 +84,18 @@ public class TestMissingWorkbook extends TestCase {
assertEquals(Cell.CELL_TYPE_FORMULA, lA1Cell.getCellType());
assertEquals(Cell.CELL_TYPE_FORMULA, lB1Cell.getCellType());
assertEquals(Cell.CELL_TYPE_FORMULA, lC1Cell.getCellType());
// Check cached values
assertEquals(10.0d, lA1Cell.getNumericCellValue(), 0.00001d);
assertEquals("POI rocks!", lB1Cell.getStringCellValue());
assertEquals(true, lC1Cell.getBooleanCellValue());
// Evaluate
FormulaEvaluator evaluator = mainWorkbook.getCreationHelper().createFormulaEvaluator();
evaluator.setIgnoreMissingWorkbooks(true);
assertEquals(Cell.CELL_TYPE_NUMERIC, evaluator.evaluateFormulaCell(lA1Cell));
assertEquals(Cell.CELL_TYPE_STRING, evaluator.evaluateFormulaCell(lB1Cell));
assertEquals(Cell.CELL_TYPE_STRING, evaluator.evaluateFormulaCell(lB1Cell));
assertEquals(Cell.CELL_TYPE_BOOLEAN, evaluator.evaluateFormulaCell(lC1Cell));
assertEquals(10.0d, lA1Cell.getNumericCellValue(), 0.00001d);