2009-05-19 12:29:51 -04:00
|
|
|
/* ====================================================================
|
|
|
|
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
|
|
|
|
|
2016-06-09 22:51:45 -04:00
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
2009-05-19 12:29:51 -04:00
|
|
|
|
|
|
|
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.hssf.usermodel;
|
|
|
|
|
2009-12-21 19:51:29 -05:00
|
|
|
import org.apache.poi.hssf.model.InternalWorkbook;
|
2009-05-19 12:29:51 -04:00
|
|
|
import org.apache.poi.hssf.record.NameRecord;
|
|
|
|
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
|
|
|
|
import org.apache.poi.ss.SpreadsheetVersion;
|
2009-09-16 20:00:57 -04:00
|
|
|
import org.apache.poi.ss.formula.EvaluationCell;
|
|
|
|
import org.apache.poi.ss.formula.EvaluationName;
|
|
|
|
import org.apache.poi.ss.formula.EvaluationSheet;
|
|
|
|
import org.apache.poi.ss.formula.EvaluationWorkbook;
|
|
|
|
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
|
|
|
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
2014-07-19 08:49:41 -04:00
|
|
|
import org.apache.poi.ss.formula.SheetIdentifier;
|
2014-07-25 06:05:57 -04:00
|
|
|
import org.apache.poi.ss.formula.SheetRangeIdentifier;
|
2014-07-19 08:49:41 -04:00
|
|
|
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
2014-07-18 14:30:16 -04:00
|
|
|
import org.apache.poi.ss.formula.ptg.NamePtg;
|
|
|
|
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
|
|
|
import org.apache.poi.ss.formula.ptg.Ptg;
|
2014-07-19 08:49:41 -04:00
|
|
|
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
|
2010-11-27 01:30:03 -05:00
|
|
|
import org.apache.poi.ss.formula.udf.UDFFinder;
|
2016-06-09 20:21:59 -04:00
|
|
|
import org.apache.poi.ss.usermodel.Table;
|
2014-07-19 08:49:41 -04:00
|
|
|
import org.apache.poi.ss.util.AreaReference;
|
|
|
|
import org.apache.poi.ss.util.CellReference;
|
2016-07-07 19:20:34 -04:00
|
|
|
import org.apache.poi.util.Internal;
|
2009-05-19 12:29:51 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal POI use only
|
|
|
|
*/
|
2016-07-07 19:20:34 -04:00
|
|
|
@Internal
|
2009-05-19 12:29:51 -04:00
|
|
|
public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
|
2014-07-19 15:23:13 -04:00
|
|
|
private final HSSFWorkbook _uBook;
|
|
|
|
private final InternalWorkbook _iBook;
|
|
|
|
|
|
|
|
public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
|
|
|
|
if (book == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return new HSSFEvaluationWorkbook(book);
|
|
|
|
}
|
|
|
|
|
|
|
|
private HSSFEvaluationWorkbook(HSSFWorkbook book) {
|
|
|
|
_uBook = book;
|
|
|
|
_iBook = book.getWorkbook();
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
|
2016-07-07 19:20:34 -04:00
|
|
|
/* (non-JavaDoc), inherit JavaDoc from EvaluationWorkbook
|
|
|
|
* @since POI 3.15 beta 3
|
|
|
|
*/
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2016-07-07 18:22:10 -04:00
|
|
|
public void clearAllCachedResultValues() {
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
|
2015-10-31 07:39:01 -04:00
|
|
|
@Override
|
|
|
|
public HSSFName createName() {
|
|
|
|
return _uBook.createName();
|
|
|
|
}
|
2014-07-19 15:23:13 -04:00
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public int getExternalSheetIndex(String sheetName) {
|
|
|
|
int sheetIndex = _uBook.getSheetIndex(sheetName);
|
|
|
|
return _iBook.checkExternSheet(sheetIndex);
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
|
|
|
return _iBook.getExternalSheetIndex(workbookName, sheetName);
|
|
|
|
}
|
2014-07-25 06:05:57 -04:00
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
|
2014-07-19 08:49:41 -04:00
|
|
|
int extIx = getSheetExtIx(sheet);
|
2014-07-19 15:23:13 -04:00
|
|
|
return new Ref3DPtg(cr, extIx);
|
2014-07-19 08:49:41 -04:00
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 08:49:41 -04:00
|
|
|
public Ptg get3DReferencePtg(AreaReference areaRef, SheetIdentifier sheet) {
|
|
|
|
int extIx = getSheetExtIx(sheet);
|
|
|
|
return new Area3DPtg(areaRef, extIx);
|
|
|
|
}
|
2015-10-31 07:39:01 -04:00
|
|
|
/**
|
|
|
|
* Return an external name (named range, function, user-defined function) Ptg
|
|
|
|
*/
|
|
|
|
@Override
|
2014-07-19 08:49:41 -04:00
|
|
|
public NameXPtg getNameXPtg(String name, SheetIdentifier sheet) {
|
|
|
|
int sheetRefIndex = getSheetExtIx(sheet);
|
2014-07-18 14:30:16 -04:00
|
|
|
return _iBook.getNameXPtg(name, sheetRefIndex, _uBook.getUDFFinder());
|
2014-07-19 15:23:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lookup a named range by its name.
|
|
|
|
*
|
|
|
|
* @param name the name to search
|
|
|
|
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
|
|
|
|
* The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
|
|
|
|
*/
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public EvaluationName getName(String name, int sheetIndex) {
|
|
|
|
for(int i=0; i < _iBook.getNumNames(); i++) {
|
|
|
|
NameRecord nr = _iBook.getNameRecord(i);
|
|
|
|
if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
|
|
|
|
return new Name(nr, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sheetIndex == -1 ? null : getName(name, -1);
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public int getSheetIndex(EvaluationSheet evalSheet) {
|
|
|
|
HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
|
|
|
|
return _uBook.getSheetIndex(sheet);
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public int getSheetIndex(String sheetName) {
|
|
|
|
return _uBook.getSheetIndex(sheetName);
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public String getSheetName(int sheetIndex) {
|
|
|
|
return _uBook.getSheetName(sheetIndex);
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public EvaluationSheet getSheet(int sheetIndex) {
|
2016-07-07 18:27:32 -04:00
|
|
|
// TODO Cache these evaluation sheets so they aren't re-generated on every getSheet call
|
2014-07-19 15:23:13 -04:00
|
|
|
return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public int convertFromExternSheetIndex(int externSheetIndex) {
|
2014-07-24 17:35:47 -04:00
|
|
|
// TODO Update this to expose first and last sheet indexes
|
|
|
|
return _iBook.getFirstSheetIndexFromExternSheetIndex(externSheetIndex);
|
2014-07-19 15:23:13 -04:00
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public ExternalSheet getExternalSheet(int externSheetIndex) {
|
|
|
|
ExternalSheet sheet = _iBook.getExternalSheet(externSheetIndex);
|
|
|
|
if (sheet == null) {
|
|
|
|
// Try to treat it as a local sheet
|
|
|
|
int localSheetIndex = convertFromExternSheetIndex(externSheetIndex);
|
2014-07-19 15:19:06 -04:00
|
|
|
if (localSheetIndex == -1) {
|
|
|
|
// The sheet referenced can't be found, sorry
|
|
|
|
return null;
|
|
|
|
}
|
2014-07-19 15:23:13 -04:00
|
|
|
if (localSheetIndex == -2) {
|
|
|
|
// Not actually sheet based at all - is workbook scoped
|
|
|
|
return null;
|
|
|
|
}
|
2014-07-24 17:25:45 -04:00
|
|
|
|
2014-07-19 15:23:13 -04:00
|
|
|
// Look up the local sheet
|
|
|
|
String sheetName = getSheetName(localSheetIndex);
|
2014-07-24 17:35:47 -04:00
|
|
|
|
|
|
|
// Is it a single local sheet, or a range?
|
|
|
|
int lastLocalSheetIndex = _iBook.getLastSheetIndexFromExternSheetIndex(externSheetIndex);
|
|
|
|
if (lastLocalSheetIndex == localSheetIndex) {
|
|
|
|
sheet = new ExternalSheet(null, sheetName);
|
|
|
|
} else {
|
|
|
|
String lastSheetName = getSheetName(lastLocalSheetIndex);
|
|
|
|
sheet = new ExternalSheetRange(null, sheetName, lastSheetName);
|
|
|
|
}
|
2014-07-19 15:23:13 -04:00
|
|
|
}
|
|
|
|
return sheet;
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws IllegalStateException: XSSF-style external references are not supported for HSSF
|
|
|
|
*/
|
|
|
|
@Override
|
2014-07-25 10:23:21 -04:00
|
|
|
public ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber) {
|
2014-07-19 15:23:13 -04:00
|
|
|
throw new IllegalStateException("XSSF-style external references are not supported for HSSF");
|
2014-07-19 15:19:06 -04:00
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:19:06 -04:00
|
|
|
public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
|
2014-07-19 15:23:13 -04:00
|
|
|
return _iBook.getExternalName(externSheetIndex, externNameIndex);
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
/**
|
|
|
|
* @throws IllegalStateException: XSSF-style external names are not supported for HSSF
|
|
|
|
*/
|
|
|
|
@Override
|
2014-07-20 13:51:51 -04:00
|
|
|
public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) {
|
|
|
|
throw new IllegalStateException("XSSF-style external names are not supported for HSSF");
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public String resolveNameXText(NameXPtg n) {
|
|
|
|
return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-24 17:25:45 -04:00
|
|
|
public String getSheetFirstNameByExternSheet(int externSheetIndex) {
|
|
|
|
return _iBook.findSheetFirstNameFromExternSheet(externSheetIndex);
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-24 17:25:45 -04:00
|
|
|
public String getSheetLastNameByExternSheet(int externSheetIndex) {
|
|
|
|
return _iBook.findSheetLastNameFromExternSheet(externSheetIndex);
|
2014-07-19 15:23:13 -04:00
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public String getNameText(NamePtg namePtg) {
|
|
|
|
return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
|
|
|
|
}
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public EvaluationName getName(NamePtg namePtg) {
|
|
|
|
int ix = namePtg.getIndex();
|
|
|
|
return new Name(_iBook.getNameRecord(ix), ix);
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2014-07-19 15:19:06 -04:00
|
|
|
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
|
2014-07-19 15:23:13 -04:00
|
|
|
HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
|
2017-01-03 20:06:30 -05:00
|
|
|
// re-parsing the formula text also works, but is a waste of time
|
|
|
|
// return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
|
|
|
|
// It is useful within the tests to make sure that all formulas POI can evaluate can also be parsed.
|
|
|
|
// see HSSFFileHandler.handleFile instead
|
2014-07-19 15:23:13 -04:00
|
|
|
FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
|
|
|
|
return fra.getFormulaTokens();
|
|
|
|
}
|
|
|
|
|
2016-07-07 18:27:32 -04:00
|
|
|
@Override
|
2010-11-28 07:03:52 -05:00
|
|
|
public UDFFinder getUDFFinder(){
|
|
|
|
return _uBook.getUDFFinder();
|
|
|
|
}
|
2009-09-16 20:00:57 -04:00
|
|
|
|
2014-07-19 15:23:13 -04:00
|
|
|
private static final class Name implements EvaluationName {
|
|
|
|
private final NameRecord _nameRecord;
|
|
|
|
private final int _index;
|
|
|
|
|
|
|
|
public Name(NameRecord nameRecord, int index) {
|
|
|
|
_nameRecord = nameRecord;
|
|
|
|
_index = index;
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public Ptg[] getNameDefinition() {
|
|
|
|
return _nameRecord.getNameDefinition();
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public String getNameText() {
|
|
|
|
return _nameRecord.getNameText();
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public boolean hasFormula() {
|
|
|
|
return _nameRecord.hasFormula();
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public boolean isFunctionName() {
|
|
|
|
return _nameRecord.isFunctionName();
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public boolean isRange() {
|
|
|
|
return _nameRecord.hasFormula(); // TODO - is this right?
|
|
|
|
}
|
2017-01-03 20:06:30 -05:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public NamePtg createPtg() {
|
|
|
|
return new NamePtg(_index);
|
|
|
|
}
|
|
|
|
}
|
2009-09-16 20:00:57 -04:00
|
|
|
|
2014-07-19 08:49:41 -04:00
|
|
|
private int getSheetExtIx(SheetIdentifier sheetIden) {
|
|
|
|
int extIx;
|
|
|
|
if (sheetIden == null) {
|
|
|
|
extIx = -1;
|
|
|
|
} else {
|
2014-07-25 06:10:52 -04:00
|
|
|
String workbookName = sheetIden.getBookName();
|
|
|
|
String firstSheetName = sheetIden.getSheetIdentifier().getName();
|
|
|
|
String lastSheetName = firstSheetName;
|
2014-07-25 06:05:57 -04:00
|
|
|
|
|
|
|
if (sheetIden instanceof SheetRangeIdentifier) {
|
2014-07-25 06:10:52 -04:00
|
|
|
lastSheetName = ((SheetRangeIdentifier)sheetIden).getLastSheetIdentifier().getName();
|
2014-07-25 06:05:57 -04:00
|
|
|
}
|
|
|
|
|
2014-07-25 06:10:52 -04:00
|
|
|
if (workbookName == null) {
|
|
|
|
int firstSheetIndex = _uBook.getSheetIndex(firstSheetName);
|
|
|
|
int lastSheetIndex = _uBook.getSheetIndex(lastSheetName);
|
|
|
|
extIx = _iBook.checkExternSheet(firstSheetIndex, lastSheetIndex);
|
2014-07-19 08:49:41 -04:00
|
|
|
} else {
|
2014-07-25 06:10:52 -04:00
|
|
|
extIx = _iBook.getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
|
2014-07-19 08:49:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return extIx;
|
|
|
|
}
|
2014-07-19 15:23:13 -04:00
|
|
|
|
2016-06-09 21:52:08 -04:00
|
|
|
@Override
|
2014-07-19 15:23:13 -04:00
|
|
|
public SpreadsheetVersion getSpreadsheetVersion(){
|
2019-03-25 12:34:15 -04:00
|
|
|
return _uBook.getSpreadsheetVersion();
|
2014-07-19 15:23:13 -04:00
|
|
|
}
|
2016-06-09 20:21:59 -04:00
|
|
|
|
2016-06-09 21:52:08 -04:00
|
|
|
/**
|
|
|
|
* @throws IllegalStateException: data tables are not supported in Excel 97-2003 format
|
|
|
|
*/
|
|
|
|
@Override
|
2016-06-09 20:21:59 -04:00
|
|
|
public Table getTable(String name) {
|
|
|
|
throw new IllegalStateException("XSSF-style tables are not supported for HSSF");
|
|
|
|
}
|
2009-05-19 12:29:51 -04:00
|
|
|
}
|