initial work on supporting calls to add-in functions
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684971 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4c9dd95587
commit
5067bab579
@ -26,6 +26,7 @@ import org.apache.poi.hssf.record.formula.*;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.AreaReference;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
@ -369,13 +370,31 @@ public final class FormulaParser {
|
||||
* @param name case preserved function name (as it was entered/appeared in the formula).
|
||||
*/
|
||||
private ParseNode function(String name) {
|
||||
NamePtg nameToken = null;
|
||||
// Note regarding parameter -
|
||||
if(!AbstractFunctionPtg.isInternalFunctionName(name)) {
|
||||
// external functions get a Name token which points to a defined name record
|
||||
nameToken = new NamePtg(name, this.book);
|
||||
|
||||
Ptg nameToken = null;
|
||||
if(!AbstractFunctionPtg.isBuiltInFunctionName(name)) {
|
||||
// user defined function
|
||||
// in the token tree, the name is more or less the first argument
|
||||
|
||||
|
||||
int nameIndex = book.getNameIndex(name);
|
||||
if (nameIndex >= 0) {
|
||||
HSSFName hName = book.getNameAt(nameIndex);
|
||||
if (!hName.isFunctionName()) {
|
||||
throw new FormulaParseException("Attempt to use name '" + name
|
||||
+ "' as a function, but defined name in workbook does not refer to a function");
|
||||
}
|
||||
|
||||
// calls to user-defined functions within the workbook
|
||||
// get a Name token which points to a defined name record
|
||||
nameToken = new NamePtg(name, this.book);
|
||||
} else {
|
||||
|
||||
nameToken = book.getNameXPtg(name);
|
||||
if (nameToken == null) {
|
||||
throw new FormulaParseException("Name '" + name
|
||||
+ "' is completely unknown in the current workbook");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Match('(');
|
||||
@ -389,11 +408,11 @@ public final class FormulaParser {
|
||||
* Generates the variable function ptg for the formula.
|
||||
* <p>
|
||||
* For IF Formulas, additional PTGs are added to the tokens
|
||||
* @param name
|
||||
* @param name a {@link NamePtg} or {@link NameXPtg} or <code>null</code>
|
||||
* @param numArgs
|
||||
* @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this function
|
||||
*/
|
||||
private ParseNode getFunction(String name, NamePtg namePtg, ParseNode[] args) {
|
||||
private ParseNode getFunction(String name, Ptg namePtg, ParseNode[] args) {
|
||||
|
||||
FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase());
|
||||
int numArgs = args.length;
|
||||
|
@ -25,11 +25,11 @@ import org.apache.poi.hssf.record.CRNCountRecord;
|
||||
import org.apache.poi.hssf.record.CRNRecord;
|
||||
import org.apache.poi.hssf.record.CountryRecord;
|
||||
import org.apache.poi.hssf.record.ExternSheetRecord;
|
||||
import org.apache.poi.hssf.record.ExternSheetSubRecord;
|
||||
import org.apache.poi.hssf.record.ExternalNameRecord;
|
||||
import org.apache.poi.hssf.record.NameRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.SupBookRecord;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
|
||||
/**
|
||||
* Link Table (OOO pdf reference: 4.10.3 ) <p/>
|
||||
@ -122,6 +122,19 @@ final class LinkTable {
|
||||
public String getNameText(int definedNameIndex) {
|
||||
return _externalNameRecords[definedNameIndex].getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs case-insensitive search
|
||||
* @return -1 if not found
|
||||
*/
|
||||
public int getIndexOfName(String name) {
|
||||
for (int i = 0; i < _externalNameRecords.length; i++) {
|
||||
if(_externalNameRecords[i].getText().equalsIgnoreCase(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private final ExternalBookBlock[] _externalBookBlocks;
|
||||
@ -270,42 +283,31 @@ final class LinkTable {
|
||||
}
|
||||
|
||||
|
||||
public short getIndexToSheet(short num) {
|
||||
return _externSheetRecord.getREFRecordAt(num).getIndexToFirstSupBook();
|
||||
public int getIndexToSheet(int extRefIndex) {
|
||||
return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
|
||||
}
|
||||
|
||||
public int getSheetIndexFromExternSheetIndex(int externSheetNumber) {
|
||||
if (externSheetNumber >= _externSheetRecord.getNumOfREFStructures()) {
|
||||
public int getSheetIndexFromExternSheetIndex(int extRefIndex) {
|
||||
if (extRefIndex >= _externSheetRecord.getNumOfRefs()) {
|
||||
return -1;
|
||||
}
|
||||
return _externSheetRecord.getREFRecordAt(externSheetNumber).getIndexToFirstSupBook();
|
||||
return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
|
||||
}
|
||||
|
||||
public short addSheetIndexToExternSheet(short sheetNumber) {
|
||||
|
||||
ExternSheetSubRecord record = new ExternSheetSubRecord();
|
||||
record.setIndexToFirstSupBook(sheetNumber);
|
||||
record.setIndexToLastSupBook(sheetNumber);
|
||||
_externSheetRecord.addREFRecord(record);
|
||||
_externSheetRecord.setNumOfREFStructures((short)(_externSheetRecord.getNumOfREFStructures() + 1));
|
||||
return (short)(_externSheetRecord.getNumOfREFStructures() - 1);
|
||||
public int addSheetIndexToExternSheet(int sheetNumber) {
|
||||
// TODO - what about the first parameter (extBookIndex)?
|
||||
return _externSheetRecord.addRef(0, sheetNumber, sheetNumber);
|
||||
}
|
||||
|
||||
public short checkExternSheet(int sheetNumber) {
|
||||
public short checkExternSheet(int sheetIndex) {
|
||||
|
||||
//Trying to find reference to this sheet
|
||||
int nESRs = _externSheetRecord.getNumOfREFStructures();
|
||||
for(short i=0; i< nESRs; i++) {
|
||||
ExternSheetSubRecord esr = _externSheetRecord.getREFRecordAt(i);
|
||||
|
||||
if (esr.getIndexToFirstSupBook() == sheetNumber
|
||||
&& esr.getIndexToLastSupBook() == sheetNumber){
|
||||
return i;
|
||||
}
|
||||
int i = _externSheetRecord.getRefIxForSheet(sheetIndex);
|
||||
if (i>=0) {
|
||||
return (short)i;
|
||||
}
|
||||
|
||||
//We Haven't found reference to this sheet
|
||||
return addSheetIndexToExternSheet((short) sheetNumber);
|
||||
return (short)addSheetIndexToExternSheet((short) sheetIndex);
|
||||
}
|
||||
|
||||
|
||||
@ -326,11 +328,31 @@ final class LinkTable {
|
||||
}
|
||||
|
||||
public int getNumberOfREFStructures() {
|
||||
return _externSheetRecord.getNumOfREFStructures();
|
||||
return _externSheetRecord.getNumOfRefs();
|
||||
}
|
||||
|
||||
public String resolveNameXText(int refIndex, int definedNameIndex) {
|
||||
short extBookIndex = _externSheetRecord.getREFRecordAt(refIndex).getIndexToSupBook();
|
||||
int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
|
||||
return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
|
||||
}
|
||||
|
||||
public NameXPtg getNameXPtg(String name) {
|
||||
// first find any external book block that contains the name:
|
||||
for (int i = 0; i < _externalBookBlocks.length; i++) {
|
||||
int definedNameIndex = _externalBookBlocks[i].getIndexOfName(name);
|
||||
if (definedNameIndex < 0) {
|
||||
continue;
|
||||
}
|
||||
// found it.
|
||||
int sheetRefIndex = findRefIndexFromExtBookIndex(i);
|
||||
if (sheetRefIndex >= 0) {
|
||||
return new NameXPtg(sheetRefIndex, definedNameIndex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int findRefIndexFromExtBookIndex(int extBookIndex) {
|
||||
return _externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex);
|
||||
}
|
||||
}
|
||||
|
@ -15,21 +15,70 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.ddf.EscherBoolProperty;
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherDggRecord;
|
||||
import org.apache.poi.ddf.EscherOptRecord;
|
||||
import org.apache.poi.ddf.EscherProperties;
|
||||
import org.apache.poi.ddf.EscherRGBProperty;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.EscherSplitMenuColorsRecord;
|
||||
import org.apache.poi.hssf.record.BOFRecord;
|
||||
import org.apache.poi.hssf.record.BackupRecord;
|
||||
import org.apache.poi.hssf.record.BookBoolRecord;
|
||||
import org.apache.poi.hssf.record.BoundSheetRecord;
|
||||
import org.apache.poi.hssf.record.CodepageRecord;
|
||||
import org.apache.poi.hssf.record.CountryRecord;
|
||||
import org.apache.poi.hssf.record.DSFRecord;
|
||||
import org.apache.poi.hssf.record.DateWindow1904Record;
|
||||
import org.apache.poi.hssf.record.DrawingGroupRecord;
|
||||
import org.apache.poi.hssf.record.EOFRecord;
|
||||
import org.apache.poi.hssf.record.ExtSSTRecord;
|
||||
import org.apache.poi.hssf.record.ExtendedFormatRecord;
|
||||
import org.apache.poi.hssf.record.ExternSheetRecord;
|
||||
import org.apache.poi.hssf.record.FileSharingRecord;
|
||||
import org.apache.poi.hssf.record.FnGroupCountRecord;
|
||||
import org.apache.poi.hssf.record.FontRecord;
|
||||
import org.apache.poi.hssf.record.FormatRecord;
|
||||
import org.apache.poi.hssf.record.HideObjRecord;
|
||||
import org.apache.poi.hssf.record.HyperlinkRecord;
|
||||
import org.apache.poi.hssf.record.InterfaceEndRecord;
|
||||
import org.apache.poi.hssf.record.InterfaceHdrRecord;
|
||||
import org.apache.poi.hssf.record.MMSRecord;
|
||||
import org.apache.poi.hssf.record.NameRecord;
|
||||
import org.apache.poi.hssf.record.PaletteRecord;
|
||||
import org.apache.poi.hssf.record.PasswordRecord;
|
||||
import org.apache.poi.hssf.record.PasswordRev4Record;
|
||||
import org.apache.poi.hssf.record.PrecisionRecord;
|
||||
import org.apache.poi.hssf.record.ProtectRecord;
|
||||
import org.apache.poi.hssf.record.ProtectionRev4Record;
|
||||
import org.apache.poi.hssf.record.RecalcIdRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RefreshAllRecord;
|
||||
import org.apache.poi.hssf.record.SSTRecord;
|
||||
import org.apache.poi.hssf.record.StyleRecord;
|
||||
import org.apache.poi.hssf.record.SupBookRecord;
|
||||
import org.apache.poi.hssf.record.TabIdRecord;
|
||||
import org.apache.poi.hssf.record.UnicodeString;
|
||||
import org.apache.poi.hssf.record.UseSelFSRecord;
|
||||
import org.apache.poi.hssf.record.WindowOneRecord;
|
||||
import org.apache.poi.hssf.record.WindowProtectRecord;
|
||||
import org.apache.poi.hssf.record.WriteAccessRecord;
|
||||
import org.apache.poi.hssf.record.WriteProtectRecord;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Low level model implementation of a Workbook. Provides creational methods
|
||||
* for settings and objects contained in the workbook object.
|
||||
@ -55,7 +104,7 @@ import java.util.Locale;
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class Workbook implements Model {
|
||||
private static final int DEBUG = POILogger.DEBUG;
|
||||
private static final int DEBUG = POILogger.DEBUG;
|
||||
|
||||
/**
|
||||
* constant used to set the "codepage" wherever "codepage" is set in records
|
||||
@ -461,19 +510,23 @@ public final class Workbook implements Model {
|
||||
/**
|
||||
* Sets the BOF for a given sheet
|
||||
*
|
||||
* @param sheetnum the number of the sheet to set the positing of the bof for
|
||||
* @param sheetIndex the number of the sheet to set the positing of the bof for
|
||||
* @param pos the actual bof position
|
||||
*/
|
||||
|
||||
public void setSheetBof(int sheetnum, int pos) {
|
||||
public void setSheetBof(int sheetIndex, int pos) {
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetnum),
|
||||
log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetIndex),
|
||||
" at pos=", new Integer(pos));
|
||||
checkSheets(sheetnum);
|
||||
(( BoundSheetRecord ) boundsheets.get(sheetnum))
|
||||
checkSheets(sheetIndex);
|
||||
getBoundSheetRec(sheetIndex)
|
||||
.setPositionOfBof(pos);
|
||||
}
|
||||
|
||||
private BoundSheetRecord getBoundSheetRec(int sheetIndex) {
|
||||
return ((BoundSheetRecord) boundsheets.get(sheetIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the backup record.
|
||||
*/
|
||||
@ -509,7 +562,7 @@ public final class Workbook implements Model {
|
||||
{
|
||||
for ( int i = 0; i < boundsheets.size(); i++ )
|
||||
{
|
||||
BoundSheetRecord boundSheetRecord = (BoundSheetRecord) boundsheets.get( i );
|
||||
BoundSheetRecord boundSheetRecord = getBoundSheetRec(i);
|
||||
if (excludeSheetIdx != i && name.equalsIgnoreCase(boundSheetRecord.getSheetname()))
|
||||
return true;
|
||||
}
|
||||
@ -526,7 +579,7 @@ public final class Workbook implements Model {
|
||||
*/
|
||||
public void setSheetName(int sheetnum, String sheetname, short encoding ) {
|
||||
checkSheets(sheetnum);
|
||||
BoundSheetRecord sheet = (BoundSheetRecord)boundsheets.get( sheetnum );
|
||||
BoundSheetRecord sheet = getBoundSheetRec(sheetnum);
|
||||
sheet.setSheetname(sheetname);
|
||||
sheet.setSheetnameLength( (byte)sheetname.length() );
|
||||
sheet.setCompressedUnicodeFlag( (byte)encoding );
|
||||
@ -548,13 +601,11 @@ public final class Workbook implements Model {
|
||||
/**
|
||||
* gets the name for a given sheet.
|
||||
*
|
||||
* @param sheetnum the sheet number (0 based)
|
||||
* @param sheetIndex the sheet number (0 based)
|
||||
* @return sheetname the name for the sheet
|
||||
*/
|
||||
|
||||
public String getSheetName(int sheetnum) {
|
||||
return (( BoundSheetRecord ) boundsheets.get(sheetnum))
|
||||
.getSheetname();
|
||||
public String getSheetName(int sheetIndex) {
|
||||
return getBoundSheetRec(sheetIndex).getSheetname();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -565,8 +616,7 @@ public final class Workbook implements Model {
|
||||
*/
|
||||
|
||||
public boolean isSheetHidden(int sheetnum) {
|
||||
BoundSheetRecord bsr = ( BoundSheetRecord ) boundsheets.get(sheetnum);
|
||||
return bsr.isHidden();
|
||||
return getBoundSheetRec(sheetnum).isHidden();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -577,8 +627,7 @@ public final class Workbook implements Model {
|
||||
*/
|
||||
|
||||
public void setSheetHidden(int sheetnum, boolean hidden) {
|
||||
BoundSheetRecord bsr = ( BoundSheetRecord ) boundsheets.get(sheetnum);
|
||||
bsr.setHidden(hidden);
|
||||
getBoundSheetRec(sheetnum).setHidden(hidden);
|
||||
}
|
||||
/**
|
||||
* get the sheet's index
|
||||
@ -851,7 +900,7 @@ public final class Workbook implements Model {
|
||||
if (record instanceof BoundSheetRecord) {
|
||||
if(!wroteBoundSheets) {
|
||||
for (int i = 0; i < boundsheets.size(); i++) {
|
||||
len+= ((BoundSheetRecord)boundsheets.get(i))
|
||||
len+= getBoundSheetRec(i)
|
||||
.serialize(pos+offset+len, data);
|
||||
}
|
||||
wroteBoundSheets = true;
|
||||
@ -1134,8 +1183,8 @@ public final class Workbook implements Model {
|
||||
retval.setWidth(( short ) 0x3a5c);
|
||||
retval.setHeight(( short ) 0x23be);
|
||||
retval.setOptions(( short ) 0x38);
|
||||
retval.setSelectedTab(( short ) 0x0);
|
||||
retval.setDisplayedTab(( short ) 0x0);
|
||||
retval.setActiveSheetIndex( 0x0);
|
||||
retval.setFirstVisibleTab(0x0);
|
||||
retval.setNumSelectedTabs(( short ) 1);
|
||||
retval.setTabWidthRatio(( short ) 0x258);
|
||||
return retval;
|
||||
@ -1882,15 +1931,15 @@ public final class Workbook implements Model {
|
||||
* @return sheet name
|
||||
*/
|
||||
public String findSheetNameFromExternSheet(short num){
|
||||
String result="";
|
||||
|
||||
short indexToSheet = linkTable.getIndexToSheet(num);
|
||||
int indexToSheet = linkTable.getIndexToSheet(num);
|
||||
|
||||
if (indexToSheet>-1) { //error check, bail out gracefully!
|
||||
result = getSheetName(indexToSheet);
|
||||
if (indexToSheet < 0) {
|
||||
// TODO - what does '-1' mean here?
|
||||
//error check, bail out gracefully!
|
||||
return "";
|
||||
}
|
||||
|
||||
return result;
|
||||
return getSheetName(indexToSheet);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2402,6 +2451,8 @@ public final class Workbook implements Model {
|
||||
public String resolveNameXText(int refIndex, int definedNameIndex) {
|
||||
return linkTable.resolveNameXText(refIndex, definedNameIndex);
|
||||
}
|
||||
|
||||
public NameXPtg getNameXPtg(String name) {
|
||||
return getOrCreateLinkTable().getNameXPtg(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -15,29 +14,85 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Title: Extern Sheet <P>
|
||||
* Description: A List of Inndexes to SupBook <P>
|
||||
* REFERENCE: <P>
|
||||
* EXTERNSHEET (0x0017)<br/>
|
||||
* A List of Indexes to EXTERNALBOOK (supplemental book) Records <p/>
|
||||
*
|
||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
|
||||
public class ExternSheetRecord extends Record {
|
||||
public final static short sid = 0x17;
|
||||
private short field_1_number_of_REF_sturcutres;
|
||||
private ArrayList field_2_REF_structures;
|
||||
public final static short sid = 0x0017;
|
||||
private List _list;
|
||||
|
||||
private final class RefSubRecord {
|
||||
public static final int ENCODED_SIZE = 6;
|
||||
|
||||
/** index to External Book Block (which starts with a EXTERNALBOOK record) */
|
||||
private int _extBookIndex;
|
||||
private int _firstSheetIndex; // may be -1 (0xFFFF)
|
||||
private int _lastSheetIndex; // may be -1 (0xFFFF)
|
||||
|
||||
|
||||
/** a Constructor for making new sub record
|
||||
*/
|
||||
public RefSubRecord(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
||||
_extBookIndex = extBookIndex;
|
||||
_firstSheetIndex = firstSheetIndex;
|
||||
_lastSheetIndex = lastSheetIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
public RefSubRecord(RecordInputStream in) {
|
||||
this(in.readShort(), in.readShort(), in.readShort());
|
||||
}
|
||||
public int getExtBookIndex(){
|
||||
return _extBookIndex;
|
||||
}
|
||||
public int getFirstSheetIndex(){
|
||||
return _firstSheetIndex;
|
||||
}
|
||||
public int getLastSheetIndex(){
|
||||
return _lastSheetIndex;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("extBook=").append(_extBookIndex);
|
||||
buffer.append(" firstSheet=").append(_firstSheetIndex);
|
||||
buffer.append(" lastSheet=").append(_lastSheetIndex);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* called by the class that is responsible for writing this sucker.
|
||||
* Subclasses should implement this so that their data is passed back in a
|
||||
* byte array.
|
||||
*
|
||||
* @param offset to begin writing at
|
||||
* @param data byte array containing instance data
|
||||
* @return number of bytes written
|
||||
*/
|
||||
public void serialize(int offset, byte [] data) {
|
||||
LittleEndian.putUShort(data, 0 + offset, _extBookIndex);
|
||||
LittleEndian.putUShort(data, 2 + offset, _firstSheetIndex);
|
||||
LittleEndian.putUShort(data, 4 + offset, _lastSheetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ExternSheetRecord() {
|
||||
field_2_REF_structures = new ArrayList();
|
||||
_list = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,72 +123,60 @@ public class ExternSheetRecord extends Record {
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
field_2_REF_structures = new ArrayList();
|
||||
_list = new ArrayList();
|
||||
|
||||
field_1_number_of_REF_sturcutres = in.readShort();
|
||||
int nItems = in.readShort();
|
||||
|
||||
for (int i = 0 ; i < field_1_number_of_REF_sturcutres ; ++i) {
|
||||
ExternSheetSubRecord rec = new ExternSheetSubRecord(in);
|
||||
for (int i = 0 ; i < nItems ; ++i) {
|
||||
RefSubRecord rec = new RefSubRecord(in);
|
||||
|
||||
field_2_REF_structures.add( rec);
|
||||
_list.add( rec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the number of the REF structors , that is in Excel file
|
||||
* @param numStruct number of REF structs
|
||||
*/
|
||||
public void setNumOfREFStructures(short numStruct) {
|
||||
field_1_number_of_REF_sturcutres = numStruct;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return the number of the REF structors , that is in Excel file
|
||||
* @return number of REF structs
|
||||
* @return number of REF structures
|
||||
*/
|
||||
public short getNumOfREFStructures() {
|
||||
return field_1_number_of_REF_sturcutres;
|
||||
public int getNumOfRefs() {
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* adds REF struct (ExternSheetSubRecord)
|
||||
* @param rec REF struct
|
||||
*/
|
||||
public void addREFRecord(ExternSheetSubRecord rec) {
|
||||
field_2_REF_structures.add(rec);
|
||||
public void addREFRecord(RefSubRecord rec) {
|
||||
_list.add(rec);
|
||||
}
|
||||
|
||||
/** returns the number of REF Records, which is in model
|
||||
* @return number of REF records
|
||||
*/
|
||||
public int getNumOfREFRecords() {
|
||||
return field_2_REF_structures.size();
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
/** returns the REF record (ExternSheetSubRecord)
|
||||
* @param elem index to place
|
||||
* @return REF record
|
||||
*/
|
||||
public ExternSheetSubRecord getREFRecordAt(int elem) {
|
||||
ExternSheetSubRecord result = ( ExternSheetSubRecord ) field_2_REF_structures.get(elem);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[EXTERNSHEET]\n");
|
||||
buffer.append(" numOfRefs = ").append(getNumOfREFStructures()).append("\n");
|
||||
for (int k=0; k < this.getNumOfREFRecords(); k++) {
|
||||
buffer.append("refrec #").append(k).append('\n');
|
||||
buffer.append(getREFRecordAt(k).toString());
|
||||
buffer.append("----refrec #").append(k).append('\n');
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int nItems = _list.size();
|
||||
sb.append("[EXTERNSHEET]\n");
|
||||
sb.append(" numOfRefs = ").append(nItems).append("\n");
|
||||
for (int i=0; i < nItems; i++) {
|
||||
sb.append("refrec #").append(i).append(": ");
|
||||
sb.append(getRef(i).toString());
|
||||
sb.append('\n');
|
||||
}
|
||||
buffer.append("[/EXTERNSHEET]\n");
|
||||
sb.append("[/EXTERNSHEET]\n");
|
||||
|
||||
|
||||
return buffer.toString();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private int getDataSize() {
|
||||
return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,24 +189,29 @@ public class ExternSheetRecord extends Record {
|
||||
* @return number of bytes written
|
||||
*/
|
||||
public int serialize(int offset, byte [] data) {
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putShort(data, 2 + offset,(short)(2 + (getNumOfREFRecords() *6)));
|
||||
int dataSize = getDataSize();
|
||||
|
||||
LittleEndian.putShort(data, 4 + offset, getNumOfREFStructures());
|
||||
int nItems = _list.size();
|
||||
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
LittleEndian.putUShort(data, 4 + offset, nItems);
|
||||
|
||||
int pos = 6 ;
|
||||
|
||||
for (int k = 0; k < getNumOfREFRecords(); k++) {
|
||||
ExternSheetSubRecord record = getREFRecordAt(k);
|
||||
System.arraycopy(record.serialize(), 0, data, pos + offset, 6);
|
||||
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
getRef(i).serialize(offset + pos, data);
|
||||
pos +=6;
|
||||
}
|
||||
return getRecordSize();
|
||||
return dataSize + 4;
|
||||
}
|
||||
|
||||
private RefSubRecord getRef(int i) {
|
||||
return (RefSubRecord) _list.get(i);
|
||||
}
|
||||
|
||||
public int getRecordSize() {
|
||||
return 4 + 2 + getNumOfREFRecords() * 6;
|
||||
return 4 + getDataSize();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,4 +220,44 @@ public class ExternSheetRecord extends Record {
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public int getExtbookIndexFromRefIndex(int refIndex) {
|
||||
return getRef(refIndex).getExtBookIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return -1 if not found
|
||||
*/
|
||||
public int findRefIndexFromExtBookIndex(int extBookIndex) {
|
||||
int nItems = _list.size();
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
if (getRef(i).getExtBookIndex() == extBookIndex) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getFirstSheetIndexFromRefIndex(int extRefIndex) {
|
||||
return getRef(extRefIndex).getFirstSheetIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of newly added ref
|
||||
*/
|
||||
public int addRef(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
||||
_list.add(new RefSubRecord(extBookIndex, firstSheetIndex, lastSheetIndex));
|
||||
return _list.size() - 1;
|
||||
}
|
||||
|
||||
public int getRefIxForSheet(int sheetIndex) {
|
||||
int nItems = _list.size();
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
RefSubRecord ref = getRef(i);
|
||||
if (ref.getFirstSheetIndex() == sheetIndex && ref.getLastSheetIndex() == sheetIndex) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1,154 +0,0 @@
|
||||
|
||||
/* ====================================================================
|
||||
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.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Title: A sub Record for Extern Sheet <P>
|
||||
* Description: Defines a named range within a workbook. <P>
|
||||
* REFERENCE: <P>
|
||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
|
||||
public class ExternSheetSubRecord extends Record {
|
||||
public final static short sid = 0xFFF; // only here for conformance, doesn't really have an sid
|
||||
private short field_1_index_to_supbook;
|
||||
private short field_2_index_to_first_supbook_sheet;
|
||||
private short field_3_index_to_last_supbook_sheet;
|
||||
|
||||
|
||||
/** a Constractor for making new sub record
|
||||
*/
|
||||
public ExternSheetSubRecord() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Extern Sheet Sub Record record and sets its fields appropriately.
|
||||
*
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
public ExternSheetSubRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
|
||||
/** Sets the Index to the sup book
|
||||
* @param index sup book index
|
||||
*/
|
||||
public void setIndexToSupBook(short index){
|
||||
field_1_index_to_supbook = index;
|
||||
}
|
||||
|
||||
/** gets the index to sup book
|
||||
* @return sup book index
|
||||
*/
|
||||
public short getIndexToSupBook(){
|
||||
return field_1_index_to_supbook;
|
||||
}
|
||||
|
||||
/** sets the index to first sheet in supbook
|
||||
* @param index index to first sheet
|
||||
*/
|
||||
public void setIndexToFirstSupBook(short index){
|
||||
field_2_index_to_first_supbook_sheet = index;
|
||||
}
|
||||
|
||||
/** gets the index to first sheet from supbook
|
||||
* @return index to first supbook
|
||||
*/
|
||||
public short getIndexToFirstSupBook(){
|
||||
return field_2_index_to_first_supbook_sheet;
|
||||
}
|
||||
|
||||
/** sets the index to last sheet in supbook
|
||||
* @param index index to last sheet
|
||||
*/
|
||||
public void setIndexToLastSupBook(short index){
|
||||
field_3_index_to_last_supbook_sheet = index;
|
||||
}
|
||||
|
||||
/** gets the index to last sheet in supbook
|
||||
* @return index to last supbook
|
||||
*/
|
||||
public short getIndexToLastSupBook(){
|
||||
return field_3_index_to_last_supbook_sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* called by constructor, should throw runtime exception in the event of a
|
||||
* record passed with a differing ID.
|
||||
*
|
||||
* @param id alleged id for this record
|
||||
*/
|
||||
protected void validateSid(short id) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
field_1_index_to_supbook = in.readShort();
|
||||
field_2_index_to_first_supbook_sheet = in.readShort();
|
||||
field_3_index_to_last_supbook_sheet = in.readShort();
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(" supbookindex =").append(getIndexToSupBook()).append('\n');
|
||||
buffer.append(" 1stsbindex =").append(getIndexToFirstSupBook()).append('\n');
|
||||
buffer.append(" lastsbindex =").append(getIndexToLastSupBook()).append('\n');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* called by the class that is responsible for writing this sucker.
|
||||
* Subclasses should implement this so that their data is passed back in a
|
||||
* byte array.
|
||||
*
|
||||
* @param offset to begin writing at
|
||||
* @param data byte array containing instance data
|
||||
* @return number of bytes written
|
||||
*/
|
||||
public int serialize(int offset, byte [] data) {
|
||||
LittleEndian.putShort(data, 0 + offset, getIndexToSupBook());
|
||||
LittleEndian.putShort(data, 2 + offset, getIndexToFirstSupBook());
|
||||
LittleEndian.putShort(data, 4 + offset, getIndexToLastSupBook());
|
||||
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
|
||||
/** returns the record size
|
||||
*/
|
||||
public int getRecordSize() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the non static version of the id for this record.
|
||||
*/
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: Name Record (aka Named Range) <P>
|
||||
* Title: DEFINEDNAME Record (0x0018) <p/>
|
||||
* Description: Defines a named range within a workbook. <P>
|
||||
* REFERENCE: <P>
|
||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||
@ -43,10 +43,7 @@ import org.apache.poi.util.StringUtil;
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class NameRecord extends Record {
|
||||
/**
|
||||
*/
|
||||
public final static short sid = 0x18; //Docs says that it is 0x218
|
||||
|
||||
public final static short sid = 0x0018;
|
||||
/**Included for completeness sake, not implemented
|
||||
*/
|
||||
public final static byte BUILTIN_CONSOLIDATE_AREA = (byte)1;
|
||||
@ -92,14 +89,15 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
public final static byte BUILTIN_SHEET_TITLE = (byte)12;
|
||||
|
||||
public static final short OPT_HIDDEN_NAME = (short) 0x0001;
|
||||
public static final short OPT_FUNCTION_NAME = (short) 0x0002;
|
||||
public static final short OPT_COMMAND_NAME = (short) 0x0004;
|
||||
public static final short OPT_MACRO = (short) 0x0008;
|
||||
public static final short OPT_COMPLEX = (short) 0x0010;
|
||||
public static final short OPT_BUILTIN = (short) 0x0020;
|
||||
public static final short OPT_BINDATA = (short) 0x1000;
|
||||
|
||||
private static final class Option {
|
||||
public static final int OPT_HIDDEN_NAME = 0x0001;
|
||||
public static final int OPT_FUNCTION_NAME = 0x0002;
|
||||
public static final int OPT_COMMAND_NAME = 0x0004;
|
||||
public static final int OPT_MACRO = 0x0008;
|
||||
public static final int OPT_COMPLEX = 0x0010;
|
||||
public static final int OPT_BUILTIN = 0x0020;
|
||||
public static final int OPT_BINDATA = 0x1000;
|
||||
}
|
||||
|
||||
private short field_1_option_flag;
|
||||
private byte field_2_keyboard_shortcut;
|
||||
@ -124,13 +122,13 @@ public final class NameRecord extends Record {
|
||||
|
||||
/** Creates new NameRecord */
|
||||
public NameRecord() {
|
||||
field_13_name_definition = new Stack();
|
||||
field_13_name_definition = new Stack();
|
||||
|
||||
field_12_name_text = new String();
|
||||
field_14_custom_menu_text = new String();
|
||||
field_15_description_text = new String();
|
||||
field_16_help_topic_text = new String();
|
||||
field_17_status_bar_text = new String();
|
||||
field_12_name_text = new String();
|
||||
field_14_custom_menu_text = new String();
|
||||
field_15_description_text = new String();
|
||||
field_16_help_topic_text = new String();
|
||||
field_17_status_bar_text = new String();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +137,7 @@ public final class NameRecord extends Record {
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
public NameRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
super(in);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,26 +146,26 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
public NameRecord(byte builtin, int sheetNumber)
|
||||
{
|
||||
this();
|
||||
this.field_12_builtIn_name = builtin;
|
||||
this.setOptionFlag((short)(this.getOptionFlag() | OPT_BUILTIN));
|
||||
this.setNameTextLength((byte)1);
|
||||
field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
|
||||
|
||||
//clearing these because they are not used with builtin records
|
||||
this();
|
||||
this.field_12_builtIn_name = builtin;
|
||||
this.setOptionFlag((short)(this.field_1_option_flag | Option.OPT_BUILTIN));
|
||||
this.setNameTextLength((byte)1);
|
||||
field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
|
||||
|
||||
//clearing these because they are not used with builtin records
|
||||
this.setCustomMenuLength((byte)0);
|
||||
this.setDescriptionTextLength((byte)0);
|
||||
this.setHelpTopicLength((byte)0);
|
||||
this.setStatusBarLength((byte)0);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** sets the option flag for the named range
|
||||
* @param flag option flag
|
||||
*/
|
||||
public void setOptionFlag(short flag){
|
||||
field_1_option_flag = flag;
|
||||
field_1_option_flag = flag;
|
||||
}
|
||||
|
||||
|
||||
@ -175,21 +173,21 @@ public final class NameRecord extends Record {
|
||||
* @param shortcut keyboard shortcut
|
||||
*/
|
||||
public void setKeyboardShortcut(byte shortcut){
|
||||
field_2_keyboard_shortcut = shortcut;
|
||||
field_2_keyboard_shortcut = shortcut;
|
||||
}
|
||||
|
||||
/** sets the name of the named range length
|
||||
* @param length name length
|
||||
*/
|
||||
public void setNameTextLength(byte length){
|
||||
field_3_length_name_text = length;
|
||||
field_3_length_name_text = length;
|
||||
}
|
||||
|
||||
/** sets the definition (reference - formula) length
|
||||
* @param length defenition length
|
||||
*/
|
||||
public void setDefinitionTextLength(short length){
|
||||
field_4_length_name_definition = length;
|
||||
field_4_length_name_definition = length;
|
||||
}
|
||||
|
||||
/** sets the index number to the extern sheet (thats is what writen in documentation
|
||||
@ -197,9 +195,9 @@ public final class NameRecord extends Record {
|
||||
* @param index extern sheet index
|
||||
*/
|
||||
public void setUnused(short index){
|
||||
field_5_index_to_sheet = index;
|
||||
field_5_index_to_sheet = index;
|
||||
|
||||
// field_6_equals_to_index_to_sheet is equal to field_5_index_to_sheet
|
||||
// field_6_equals_to_index_to_sheet is equal to field_5_index_to_sheet
|
||||
// field_6_equals_to_index_to_sheet = index;
|
||||
}
|
||||
|
||||
@ -209,7 +207,7 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
public int getSheetNumber()
|
||||
{
|
||||
return field_6_sheetNumber;
|
||||
return field_6_sheetNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,14 +215,14 @@ public final class NameRecord extends Record {
|
||||
* @see FnGroupCountRecord
|
||||
*/
|
||||
public byte getFnGroup() {
|
||||
int masked = field_1_option_flag & 0x0fc0;
|
||||
return (byte) (masked >> 4);
|
||||
int masked = field_1_option_flag & 0x0fc0;
|
||||
return (byte) (masked >> 4);
|
||||
}
|
||||
|
||||
|
||||
public void setSheetNumber(int value)
|
||||
{
|
||||
field_6_sheetNumber = value;
|
||||
field_6_sheetNumber = value;
|
||||
}
|
||||
|
||||
|
||||
@ -232,87 +230,87 @@ public final class NameRecord extends Record {
|
||||
* @param length custom menu length
|
||||
*/
|
||||
public void setCustomMenuLength(byte length){
|
||||
field_7_length_custom_menu = length;
|
||||
field_7_length_custom_menu = length;
|
||||
}
|
||||
|
||||
/** sets the length of named range description
|
||||
* @param length description length
|
||||
*/
|
||||
public void setDescriptionTextLength(byte length){
|
||||
field_8_length_description_text = length;
|
||||
field_8_length_description_text = length;
|
||||
}
|
||||
|
||||
/** sets the help topic length
|
||||
* @param length help topic length
|
||||
*/
|
||||
public void setHelpTopicLength(byte length){
|
||||
field_9_length_help_topic_text = length;
|
||||
field_9_length_help_topic_text = length;
|
||||
}
|
||||
|
||||
/** sets the length of the status bar text
|
||||
* @param length status bar text length
|
||||
*/
|
||||
public void setStatusBarLength(byte length){
|
||||
field_10_length_status_bar_text = length;
|
||||
field_10_length_status_bar_text = length;
|
||||
}
|
||||
|
||||
/** sets the compressed unicode flag
|
||||
* @param flag unicode flag
|
||||
*/
|
||||
public void setCompressedUnicodeFlag(byte flag) {
|
||||
field_11_compressed_unicode_flag = flag;
|
||||
field_11_compressed_unicode_flag = flag;
|
||||
}
|
||||
|
||||
/** sets the name of the named range
|
||||
* @param name named range name
|
||||
*/
|
||||
public void setNameText(String name){
|
||||
field_12_name_text = name;
|
||||
setCompressedUnicodeFlag(
|
||||
field_12_name_text = name;
|
||||
setCompressedUnicodeFlag(
|
||||
StringUtil.hasMultibyte(name) ? (byte)1 : (byte)0
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
/** sets the custom menu text
|
||||
* @param text custom menu text
|
||||
*/
|
||||
public void setCustomMenuText(String text){
|
||||
field_14_custom_menu_text = text;
|
||||
field_14_custom_menu_text = text;
|
||||
}
|
||||
|
||||
/** sets the description text
|
||||
* @param text the description text
|
||||
*/
|
||||
public void setDescriptionText(String text){
|
||||
field_15_description_text = text;
|
||||
field_15_description_text = text;
|
||||
}
|
||||
|
||||
/** sets the help topic text
|
||||
* @param text help topix text
|
||||
*/
|
||||
public void setHelpTopicText(String text){
|
||||
field_16_help_topic_text = text;
|
||||
field_16_help_topic_text = text;
|
||||
}
|
||||
|
||||
/** sets the status bar text
|
||||
* @param text status bar text
|
||||
*/
|
||||
public void setStatusBarText(String text){
|
||||
field_17_status_bar_text = text;
|
||||
field_17_status_bar_text = text;
|
||||
}
|
||||
|
||||
/** gets the option flag
|
||||
* @return option flag
|
||||
*/
|
||||
public short getOptionFlag(){
|
||||
return field_1_option_flag;
|
||||
return field_1_option_flag;
|
||||
}
|
||||
|
||||
/** returns the keyboard shortcut
|
||||
* @return keyboard shortcut
|
||||
*/
|
||||
public byte getKeyboardShortcut(){
|
||||
return field_2_keyboard_shortcut ;
|
||||
return field_2_keyboard_shortcut ;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,7 +318,7 @@ public final class NameRecord extends Record {
|
||||
* @return name length
|
||||
*/
|
||||
public byte getNameTextLength(){
|
||||
return field_3_length_name_text;
|
||||
return field_3_length_name_text;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,92 +336,90 @@ public final class NameRecord extends Record {
|
||||
* @return definition length
|
||||
*/
|
||||
public short getDefinitionLength(){
|
||||
return field_4_length_name_definition;
|
||||
return field_4_length_name_definition;
|
||||
}
|
||||
|
||||
/** gets the index to extern sheet
|
||||
* @return index to extern sheet
|
||||
*/
|
||||
public short getUnused(){
|
||||
return field_5_index_to_sheet;
|
||||
return field_5_index_to_sheet;
|
||||
}
|
||||
|
||||
/** gets the custom menu length
|
||||
* @return custom menu length
|
||||
*/
|
||||
public byte getCustomMenuLength(){
|
||||
return field_7_length_custom_menu;
|
||||
return field_7_length_custom_menu;
|
||||
}
|
||||
|
||||
/** gets the description text length
|
||||
* @return description text length
|
||||
*/
|
||||
public byte getDescriptionTextLength(){
|
||||
return field_8_length_description_text;
|
||||
return field_8_length_description_text;
|
||||
}
|
||||
|
||||
/** gets the help topic length
|
||||
* @return help topic length
|
||||
*/
|
||||
public byte getHelpTopicLength(){
|
||||
return field_9_length_help_topic_text;
|
||||
return field_9_length_help_topic_text;
|
||||
}
|
||||
|
||||
/** get the status bar text length
|
||||
* @return satus bar length
|
||||
*/
|
||||
public byte getStatusBarLength(){
|
||||
return field_10_length_status_bar_text;
|
||||
return field_10_length_status_bar_text;
|
||||
}
|
||||
|
||||
/** gets the name compressed Unicode flag
|
||||
* @return compressed unicode flag
|
||||
*/
|
||||
public byte getCompressedUnicodeFlag() {
|
||||
return field_11_compressed_unicode_flag;
|
||||
return field_11_compressed_unicode_flag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if name is hidden
|
||||
*/
|
||||
public boolean isHiddenName() {
|
||||
return (field_1_option_flag & OPT_HIDDEN_NAME) != 0;
|
||||
return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if name is a function
|
||||
*/
|
||||
public boolean isFunctionName() {
|
||||
return (field_1_option_flag & OPT_FUNCTION_NAME) != 0;
|
||||
return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if name is a command
|
||||
*/
|
||||
public boolean isCommandName() {
|
||||
return (field_1_option_flag & OPT_COMMAND_NAME) != 0;
|
||||
return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if function macro or command macro
|
||||
*/
|
||||
public boolean isMacro() {
|
||||
return (field_1_option_flag & OPT_MACRO) != 0;
|
||||
return (field_1_option_flag & Option.OPT_MACRO) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if array formula or user defined
|
||||
*/
|
||||
public boolean isComplexFunction() {
|
||||
return (field_1_option_flag & OPT_COMPLEX) != 0;
|
||||
return (field_1_option_flag & Option.OPT_COMPLEX) != 0;
|
||||
}
|
||||
|
||||
|
||||
/**Convenience Function to determine if the name is a built-in name
|
||||
*/
|
||||
public boolean isBuiltInName()
|
||||
{
|
||||
return ((this.getOptionFlag() & OPT_BUILTIN) != 0);
|
||||
return ((this.field_1_option_flag & Option.OPT_BUILTIN) != 0);
|
||||
}
|
||||
|
||||
|
||||
@ -440,7 +436,7 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
public byte getBuiltInName()
|
||||
{
|
||||
return this.field_12_builtIn_name;
|
||||
return this.field_12_builtIn_name;
|
||||
}
|
||||
|
||||
|
||||
@ -448,39 +444,39 @@ public final class NameRecord extends Record {
|
||||
* @return definition -- can be null if we cant parse ptgs
|
||||
*/
|
||||
public List getNameDefinition() {
|
||||
return field_13_name_definition;
|
||||
return field_13_name_definition;
|
||||
}
|
||||
|
||||
public void setNameDefinition(Stack nameDefinition) {
|
||||
field_13_name_definition = nameDefinition;
|
||||
field_13_name_definition = nameDefinition;
|
||||
}
|
||||
|
||||
/** get the custom menu text
|
||||
* @return custom menu text
|
||||
*/
|
||||
public String getCustomMenuText(){
|
||||
return field_14_custom_menu_text;
|
||||
return field_14_custom_menu_text;
|
||||
}
|
||||
|
||||
/** gets the description text
|
||||
* @return description text
|
||||
*/
|
||||
public String getDescriptionText(){
|
||||
return field_15_description_text;
|
||||
return field_15_description_text;
|
||||
}
|
||||
|
||||
/** get the help topic text
|
||||
* @return gelp topic text
|
||||
*/
|
||||
public String getHelpTopicText(){
|
||||
return field_16_help_topic_text;
|
||||
return field_16_help_topic_text;
|
||||
}
|
||||
|
||||
/** gets the status bar text
|
||||
* @return status bar text
|
||||
*/
|
||||
public String getStatusBarText(){
|
||||
return field_17_status_bar_text;
|
||||
return field_17_status_bar_text;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -490,9 +486,9 @@ public final class NameRecord extends Record {
|
||||
* @param id alleged id for this record
|
||||
*/
|
||||
protected void validateSid(short id) {
|
||||
if (id != sid) {
|
||||
throw new RecordFormatException("NOT A valid Name RECORD");
|
||||
}
|
||||
if (id != sid) {
|
||||
throw new RecordFormatException("NOT A valid Name RECORD");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -504,21 +500,21 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
public int serialize( int offset, byte[] data )
|
||||
{
|
||||
LittleEndian.putShort( data, 0 + offset, sid );
|
||||
short size = (short)( 15 + getTextsLength() + getNameDefinitionSize());
|
||||
LittleEndian.putShort( data, 2 + offset, size );
|
||||
// size defined below
|
||||
LittleEndian.putShort( data, 4 + offset, getOptionFlag() );
|
||||
data[6 + offset] = getKeyboardShortcut();
|
||||
data[7 + offset] = getNameTextLength();
|
||||
LittleEndian.putShort( data, 8 + offset, getDefinitionLength() );
|
||||
LittleEndian.putShort( data, 10 + offset, getUnused() );
|
||||
LittleEndian.putUShort( data, 12 + offset, field_6_sheetNumber);
|
||||
data[14 + offset] = getCustomMenuLength();
|
||||
data[15 + offset] = getDescriptionTextLength();
|
||||
data[16 + offset] = getHelpTopicLength();
|
||||
data[17 + offset] = getStatusBarLength();
|
||||
data[18 + offset] = getCompressedUnicodeFlag();
|
||||
LittleEndian.putShort( data, 0 + offset, sid );
|
||||
short size = (short)( 15 + getTextsLength() + getNameDefinitionSize());
|
||||
LittleEndian.putShort( data, 2 + offset, size );
|
||||
// size defined below
|
||||
LittleEndian.putShort( data, 4 + offset, getOptionFlag() );
|
||||
data[6 + offset] = getKeyboardShortcut();
|
||||
data[7 + offset] = getNameTextLength();
|
||||
LittleEndian.putShort( data, 8 + offset, getDefinitionLength() );
|
||||
LittleEndian.putShort( data, 10 + offset, getUnused() );
|
||||
LittleEndian.putUShort( data, 12 + offset, field_6_sheetNumber);
|
||||
data[14 + offset] = getCustomMenuLength();
|
||||
data[15 + offset] = getDescriptionTextLength();
|
||||
data[16 + offset] = getHelpTopicLength();
|
||||
data[17 + offset] = getStatusBarLength();
|
||||
data[18 + offset] = getCompressedUnicodeFlag();
|
||||
|
||||
int start_of_name_definition = 19 + field_3_length_name_text;
|
||||
|
||||
@ -536,20 +532,20 @@ public final class NameRecord extends Record {
|
||||
Ptg.serializePtgStack(field_13_name_definition, data, start_of_name_definition + offset );
|
||||
|
||||
|
||||
int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition;
|
||||
StringUtil.putCompressedUnicode( getCustomMenuText(), data, start_of_custom_menu_text + offset );
|
||||
int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition;
|
||||
StringUtil.putCompressedUnicode( getCustomMenuText(), data, start_of_custom_menu_text + offset );
|
||||
|
||||
int start_of_description_text = start_of_custom_menu_text + field_7_length_custom_menu;
|
||||
StringUtil.putCompressedUnicode( getDescriptionText(), data, start_of_description_text + offset );
|
||||
int start_of_description_text = start_of_custom_menu_text + field_7_length_custom_menu;
|
||||
StringUtil.putCompressedUnicode( getDescriptionText(), data, start_of_description_text + offset );
|
||||
|
||||
int start_of_help_topic_text = start_of_description_text + field_8_length_description_text;
|
||||
StringUtil.putCompressedUnicode( getHelpTopicText(), data, start_of_help_topic_text + offset );
|
||||
int start_of_help_topic_text = start_of_description_text + field_8_length_description_text;
|
||||
StringUtil.putCompressedUnicode( getHelpTopicText(), data, start_of_help_topic_text + offset );
|
||||
|
||||
int start_of_status_bar_text = start_of_help_topic_text + field_9_length_help_topic_text;
|
||||
StringUtil.putCompressedUnicode( getStatusBarText(), data, start_of_status_bar_text + offset );
|
||||
int start_of_status_bar_text = start_of_help_topic_text + field_9_length_help_topic_text;
|
||||
StringUtil.putCompressedUnicode( getStatusBarText(), data, start_of_status_bar_text + offset );
|
||||
|
||||
return getRecordSize();
|
||||
/* } */
|
||||
return getRecordSize();
|
||||
/* } */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -557,83 +553,83 @@ public final class NameRecord extends Record {
|
||||
* @return total length
|
||||
*/
|
||||
public int getTextsLength(){
|
||||
int result;
|
||||
int result;
|
||||
|
||||
result = getRawNameTextLength() + getDescriptionTextLength() +
|
||||
result = getRawNameTextLength() + getDescriptionTextLength() +
|
||||
getHelpTopicLength() + getStatusBarLength();
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private int getNameDefinitionSize() {
|
||||
int result = 0;
|
||||
List list = field_13_name_definition;
|
||||
|
||||
for (int k = 0; k < list.size(); k++)
|
||||
{
|
||||
List list = field_13_name_definition;
|
||||
|
||||
for (int k = 0; k < list.size(); k++)
|
||||
{
|
||||
Ptg ptg = ( Ptg ) list.get(k);
|
||||
|
||||
result += ptg.getSize();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** returns the record size
|
||||
*/
|
||||
public int getRecordSize(){
|
||||
int result;
|
||||
int result;
|
||||
|
||||
result = 19 + getTextsLength() + getNameDefinitionSize();
|
||||
|
||||
result = 19 + getTextsLength() + getNameDefinitionSize();
|
||||
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** gets the extern sheet number
|
||||
* @return extern sheet index
|
||||
*/
|
||||
public short getExternSheetNumber(){
|
||||
if (field_13_name_definition == null || field_13_name_definition.isEmpty()) return 0;
|
||||
Ptg ptg = (Ptg) field_13_name_definition.peek();
|
||||
short result = 0;
|
||||
if (field_13_name_definition == null || field_13_name_definition.isEmpty()) return 0;
|
||||
Ptg ptg = (Ptg) field_13_name_definition.peek();
|
||||
short result = 0;
|
||||
|
||||
if (ptg.getClass() == Area3DPtg.class){
|
||||
result = ((Area3DPtg) ptg).getExternSheetIndex();
|
||||
if (ptg.getClass() == Area3DPtg.class){
|
||||
result = ((Area3DPtg) ptg).getExternSheetIndex();
|
||||
|
||||
} else if (ptg.getClass() == Ref3DPtg.class){
|
||||
result = ((Ref3DPtg) ptg).getExternSheetIndex();
|
||||
}
|
||||
} else if (ptg.getClass() == Ref3DPtg.class){
|
||||
result = ((Ref3DPtg) ptg).getExternSheetIndex();
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** sets the extern sheet number
|
||||
* @param externSheetNumber extern sheet number
|
||||
*/
|
||||
public void setExternSheetNumber(short externSheetNumber){
|
||||
Ptg ptg;
|
||||
Ptg ptg;
|
||||
|
||||
if (field_13_name_definition == null || field_13_name_definition.isEmpty()){
|
||||
field_13_name_definition = new Stack();
|
||||
ptg = createNewPtg();
|
||||
} else {
|
||||
ptg = (Ptg) field_13_name_definition.peek();
|
||||
}
|
||||
if (field_13_name_definition == null || field_13_name_definition.isEmpty()){
|
||||
field_13_name_definition = new Stack();
|
||||
ptg = createNewPtg();
|
||||
} else {
|
||||
ptg = (Ptg) field_13_name_definition.peek();
|
||||
}
|
||||
|
||||
if (ptg.getClass() == Area3DPtg.class){
|
||||
((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
||||
if (ptg.getClass() == Area3DPtg.class){
|
||||
((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
||||
|
||||
} else if (ptg.getClass() == Ref3DPtg.class){
|
||||
((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
||||
}
|
||||
} else if (ptg.getClass() == Ref3DPtg.class){
|
||||
((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Ptg createNewPtg(){
|
||||
Ptg ptg = new Area3DPtg();
|
||||
field_13_name_definition.push(ptg);
|
||||
Ptg ptg = new Area3DPtg();
|
||||
field_13_name_definition.push(ptg);
|
||||
|
||||
return ptg;
|
||||
return ptg;
|
||||
}
|
||||
|
||||
/** gets the reference , the area only (range)
|
||||
@ -647,55 +643,55 @@ public final class NameRecord extends Record {
|
||||
* @param ref area reference
|
||||
*/
|
||||
public void setAreaReference(String ref){
|
||||
//Trying to find if what ptg do we need
|
||||
RangeAddress ra = new RangeAddress(ref);
|
||||
Ptg oldPtg;
|
||||
Ptg ptg;
|
||||
//Trying to find if what ptg do we need
|
||||
RangeAddress ra = new RangeAddress(ref);
|
||||
Ptg oldPtg;
|
||||
Ptg ptg;
|
||||
|
||||
if (field_13_name_definition==null ||field_13_name_definition.isEmpty()){
|
||||
field_13_name_definition = new Stack();
|
||||
oldPtg = createNewPtg();
|
||||
} else {
|
||||
//Trying to find extern sheet index
|
||||
oldPtg = (Ptg) field_13_name_definition.pop();
|
||||
}
|
||||
if (field_13_name_definition==null ||field_13_name_definition.isEmpty()){
|
||||
field_13_name_definition = new Stack();
|
||||
oldPtg = createNewPtg();
|
||||
} else {
|
||||
//Trying to find extern sheet index
|
||||
oldPtg = (Ptg) field_13_name_definition.pop();
|
||||
}
|
||||
|
||||
short externSheetIndex = 0;
|
||||
short externSheetIndex = 0;
|
||||
|
||||
if (oldPtg.getClass() == Area3DPtg.class){
|
||||
externSheetIndex = ((Area3DPtg) oldPtg).getExternSheetIndex();
|
||||
if (oldPtg.getClass() == Area3DPtg.class){
|
||||
externSheetIndex = ((Area3DPtg) oldPtg).getExternSheetIndex();
|
||||
|
||||
} else if (oldPtg.getClass() == Ref3DPtg.class){
|
||||
externSheetIndex = ((Ref3DPtg) oldPtg).getExternSheetIndex();
|
||||
}
|
||||
} else if (oldPtg.getClass() == Ref3DPtg.class){
|
||||
externSheetIndex = ((Ref3DPtg) oldPtg).getExternSheetIndex();
|
||||
}
|
||||
|
||||
if (ra.hasRange()) {
|
||||
if (ra.hasRange()) {
|
||||
// Is it contiguous or not?
|
||||
AreaReference[] refs =
|
||||
AreaReference.generateContiguous(ref);
|
||||
this.setDefinitionTextLength((short)0);
|
||||
this.setDefinitionTextLength((short)0);
|
||||
|
||||
// Add the area reference(s)
|
||||
// Add the area reference(s)
|
||||
for(int i=0; i<refs.length; i++) {
|
||||
ptg = new Area3DPtg();
|
||||
((Area3DPtg) ptg).setExternSheetIndex(externSheetIndex);
|
||||
((Area3DPtg) ptg).setArea(refs[i].formatAsString());
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
|
||||
ptg = new Area3DPtg();
|
||||
((Area3DPtg) ptg).setExternSheetIndex(externSheetIndex);
|
||||
((Area3DPtg) ptg).setArea(refs[i].formatAsString());
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
|
||||
}
|
||||
// And then a union if we had more than one area
|
||||
if(refs.length > 1) {
|
||||
ptg = UnionPtg.instance;
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
|
||||
}
|
||||
} else {
|
||||
ptg = new Ref3DPtg();
|
||||
((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex);
|
||||
((Ref3DPtg) ptg).setArea(ref);
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength((short)ptg.getSize());
|
||||
}
|
||||
} else {
|
||||
ptg = new Ref3DPtg();
|
||||
((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex);
|
||||
((Ref3DPtg) ptg).setArea(ref);
|
||||
field_13_name_definition.push(ptg);
|
||||
this.setDefinitionTextLength((short)ptg.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -705,47 +701,47 @@ public final class NameRecord extends Record {
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
field_1_option_flag = in.readShort();
|
||||
field_2_keyboard_shortcut = in.readByte();
|
||||
field_3_length_name_text = in.readByte();
|
||||
field_4_length_name_definition = in.readShort();
|
||||
field_5_index_to_sheet = in.readShort();
|
||||
field_6_sheetNumber = in.readUShort();
|
||||
field_7_length_custom_menu = in.readByte();
|
||||
field_8_length_description_text = in.readByte();
|
||||
field_9_length_help_topic_text = in.readByte();
|
||||
field_10_length_status_bar_text = in.readByte();
|
||||
|
||||
//store the name in byte form if it's a builtin name
|
||||
field_11_compressed_unicode_flag= in.readByte();
|
||||
if (this.isBuiltInName()) {
|
||||
field_12_builtIn_name = in.readByte();
|
||||
} else {
|
||||
if (field_11_compressed_unicode_flag == 1) {
|
||||
field_12_name_text = in.readUnicodeLEString(field_3_length_name_text);
|
||||
} else {
|
||||
field_12_name_text = in.readCompressedUnicode(field_3_length_name_text);
|
||||
}
|
||||
}
|
||||
|
||||
field_13_name_definition = Ptg.createParsedExpressionTokens(field_4_length_name_definition, in);
|
||||
field_1_option_flag = in.readShort();
|
||||
field_2_keyboard_shortcut = in.readByte();
|
||||
field_3_length_name_text = in.readByte();
|
||||
field_4_length_name_definition = in.readShort();
|
||||
field_5_index_to_sheet = in.readShort();
|
||||
field_6_sheetNumber = in.readUShort();
|
||||
field_7_length_custom_menu = in.readByte();
|
||||
field_8_length_description_text = in.readByte();
|
||||
field_9_length_help_topic_text = in.readByte();
|
||||
field_10_length_status_bar_text = in.readByte();
|
||||
|
||||
//store the name in byte form if it's a builtin name
|
||||
field_11_compressed_unicode_flag= in.readByte();
|
||||
if (this.isBuiltInName()) {
|
||||
field_12_builtIn_name = in.readByte();
|
||||
} else {
|
||||
if (field_11_compressed_unicode_flag == 1) {
|
||||
field_12_name_text = in.readUnicodeLEString(field_3_length_name_text);
|
||||
} else {
|
||||
field_12_name_text = in.readCompressedUnicode(field_3_length_name_text);
|
||||
}
|
||||
}
|
||||
|
||||
field_13_name_definition = Ptg.createParsedExpressionTokens(field_4_length_name_definition, in);
|
||||
|
||||
//Who says that this can only ever be compressed unicode???
|
||||
field_14_custom_menu_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_7_length_custom_menu));
|
||||
//Who says that this can only ever be compressed unicode???
|
||||
field_14_custom_menu_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_7_length_custom_menu));
|
||||
|
||||
field_15_description_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_8_length_description_text));
|
||||
field_15_description_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_8_length_description_text));
|
||||
|
||||
field_16_help_topic_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_9_length_help_topic_text));
|
||||
field_16_help_topic_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_9_length_help_topic_text));
|
||||
|
||||
field_17_status_bar_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_10_length_status_bar_text));
|
||||
/*} */
|
||||
field_17_status_bar_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_10_length_status_bar_text));
|
||||
/*} */
|
||||
}
|
||||
|
||||
/**
|
||||
* return the non static version of the id for this record.
|
||||
*/
|
||||
public short getSid() {
|
||||
return sid;
|
||||
return sid;
|
||||
}
|
||||
/*
|
||||
20 00
|
||||
@ -802,53 +798,53 @@ public final class NameRecord extends Record {
|
||||
* @see Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[NAME]\n");
|
||||
buffer.append(" .option flags = ").append( HexDump.toHex( field_1_option_flag ) )
|
||||
.append("\n");
|
||||
buffer.append(" .keyboard shortcut = ").append( HexDump.toHex( field_2_keyboard_shortcut ) )
|
||||
.append("\n");
|
||||
buffer.append(" .length of the name = ").append( field_3_length_name_text )
|
||||
.append("\n");
|
||||
buffer.append(" .size of the formula data = ").append( field_4_length_name_definition )
|
||||
.append("\n");
|
||||
buffer.append(" .unused = ").append( field_5_index_to_sheet )
|
||||
.append("\n");
|
||||
buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of menu text (character count) = ").append( field_7_length_custom_menu )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of description text (character count) = ").append( field_8_length_description_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of help topic text (character count) = ").append( field_9_length_help_topic_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of status bar text (character count) = ").append( field_10_length_status_bar_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Name (Unicode flag) = ").append( field_11_compressed_unicode_flag )
|
||||
.append("\n");
|
||||
buffer.append(" .Name (Unicode text) = ").append( getNameText() )
|
||||
.append("\n");
|
||||
|
||||
buffer.append(" .Parts (" + field_13_name_definition.size() +"):")
|
||||
.append("\n");
|
||||
Iterator it = field_13_name_definition.iterator();
|
||||
while(it.hasNext()) {
|
||||
buffer.append("[NAME]\n");
|
||||
buffer.append(" .option flags = ").append( HexDump.toHex( field_1_option_flag ) )
|
||||
.append("\n");
|
||||
buffer.append(" .keyboard shortcut = ").append( HexDump.toHex( field_2_keyboard_shortcut ) )
|
||||
.append("\n");
|
||||
buffer.append(" .length of the name = ").append( field_3_length_name_text )
|
||||
.append("\n");
|
||||
buffer.append(" .size of the formula data = ").append( field_4_length_name_definition )
|
||||
.append("\n");
|
||||
buffer.append(" .unused = ").append( field_5_index_to_sheet )
|
||||
.append("\n");
|
||||
buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of menu text (character count) = ").append( field_7_length_custom_menu )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of description text (character count) = ").append( field_8_length_description_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of help topic text (character count) = ").append( field_9_length_help_topic_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Length of status bar text (character count) = ").append( field_10_length_status_bar_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Name (Unicode flag) = ").append( field_11_compressed_unicode_flag )
|
||||
.append("\n");
|
||||
buffer.append(" .Name (Unicode text) = ").append( getNameText() )
|
||||
.append("\n");
|
||||
|
||||
buffer.append(" .Parts (" + field_13_name_definition.size() +"):")
|
||||
.append("\n");
|
||||
Iterator it = field_13_name_definition.iterator();
|
||||
while(it.hasNext()) {
|
||||
Ptg ptg = (Ptg)it.next();
|
||||
buffer.append(" " + ptg.toString()).append("\n");
|
||||
}
|
||||
|
||||
buffer.append(" .Menu text (Unicode string without length field) = ").append( field_14_custom_menu_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Description text (Unicode string without length field) = ").append( field_15_description_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Help topic text (Unicode string without length field) = ").append( field_16_help_topic_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Status bar text (Unicode string without length field) = ").append( field_17_status_bar_text )
|
||||
.append("\n");
|
||||
buffer.append("[/NAME]\n");
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
buffer.append(" .Menu text (Unicode string without length field) = ").append( field_14_custom_menu_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Description text (Unicode string without length field) = ").append( field_15_description_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Help topic text (Unicode string without length field) = ").append( field_16_help_topic_text )
|
||||
.append("\n");
|
||||
buffer.append(" .Status bar text (Unicode string without length field) = ").append( field_17_status_bar_text )
|
||||
.append("\n");
|
||||
buffer.append("[/NAME]\n");
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**Creates a human readable name for built in types
|
||||
@ -856,23 +852,23 @@ public final class NameRecord extends Record {
|
||||
*/
|
||||
protected String translateBuiltInName(byte name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate";
|
||||
case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close";
|
||||
case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate";
|
||||
case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open";
|
||||
case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area";
|
||||
case NameRecord.BUILTIN_CRITERIA : return "Criteria";
|
||||
case NameRecord.BUILTIN_DATABASE : return "Database";
|
||||
case NameRecord.BUILTIN_DATA_FORM : return "Data_Form";
|
||||
case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area";
|
||||
case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
|
||||
case NameRecord.BUILTIN_RECORDER : return "Recorder";
|
||||
case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
|
||||
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
switch (name)
|
||||
{
|
||||
case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate";
|
||||
case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close";
|
||||
case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate";
|
||||
case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open";
|
||||
case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area";
|
||||
case NameRecord.BUILTIN_CRITERIA : return "Criteria";
|
||||
case NameRecord.BUILTIN_DATABASE : return "Database";
|
||||
case NameRecord.BUILTIN_DATA_FORM : return "Data_Form";
|
||||
case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area";
|
||||
case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
|
||||
case NameRecord.BUILTIN_RECORDER : return "Recorder";
|
||||
case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
|
||||
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Title: Sup Book (EXTERNALBOOK) <P>
|
||||
* Description: A External Workbook Description (Suplemental Book)
|
||||
* Description: A External Workbook Description (Supplemental Book)
|
||||
* Its only a dummy record for making new ExternSheet Record <P>
|
||||
* REFERENCE: 5.38<P>
|
||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||
|
@ -110,7 +110,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
* @return <code>true</code> if the name specifies a standard worksheet function,
|
||||
* <code>false</code> if the name should be assumed to be an external function.
|
||||
*/
|
||||
public static final boolean isInternalFunctionName(String name) {
|
||||
public static final boolean isBuiltInFunctionName(String name) {
|
||||
short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
|
||||
return ix >= 0;
|
||||
}
|
||||
|
@ -22,41 +22,55 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aviks
|
||||
*
|
||||
* @author aviks
|
||||
*/
|
||||
public final class NameXPtg extends OperandPtg {
|
||||
public final static short sid = 0x39;
|
||||
private final static int SIZE = 7;
|
||||
private short field_1_ixals; // index to REF entry in externsheet record
|
||||
private short field_2_ilbl; //index to defined name or externname table(1 based)
|
||||
private short field_3_reserved; // reserved must be 0
|
||||
public final static short sid = 0x39;
|
||||
private final static int SIZE = 7;
|
||||
|
||||
/** index to REF entry in externsheet record */
|
||||
private int _sheetRefIndex;
|
||||
/** index to defined name or externname table(1 based) */
|
||||
private int _nameNumber;
|
||||
/** reserved must be 0 */
|
||||
private int _reserved;
|
||||
|
||||
public NameXPtg(RecordInputStream in) {
|
||||
field_1_ixals = in.readShort();
|
||||
field_2_ilbl = in.readShort();
|
||||
field_3_reserved = in.readShort();
|
||||
}
|
||||
private NameXPtg(int sheetRefIndex, int nameNumber, int reserved) {
|
||||
_sheetRefIndex = sheetRefIndex;
|
||||
_nameNumber = nameNumber;
|
||||
_reserved = reserved;
|
||||
}
|
||||
|
||||
public void writeBytes(byte [] array, int offset) {
|
||||
array[ offset + 0 ] = (byte)(sid + getPtgClass());
|
||||
LittleEndian.putShort(array, offset + 1, field_1_ixals);
|
||||
LittleEndian.putShort(array,offset+3, field_2_ilbl);
|
||||
LittleEndian.putShort(array, offset + 5, field_3_reserved);
|
||||
}
|
||||
/**
|
||||
* @param sheetRefIndex index to REF entry in externsheet record
|
||||
* @param nameIndex index to defined name or externname table
|
||||
*/
|
||||
public NameXPtg(int sheetRefIndex, int nameIndex) {
|
||||
this(sheetRefIndex, nameIndex + 1, 0);
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
public NameXPtg(RecordInputStream in) {
|
||||
this(in.readUShort(), in.readUShort(), in.readUShort());
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
{
|
||||
// -1 to convert definedNameIndex from 1-based to zero-based
|
||||
return book.resolveNameXText(field_1_ixals, field_2_ilbl-1);
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
LittleEndian.putByte(array, offset + 0, sid + getPtgClass());
|
||||
LittleEndian.putUShort(array, offset + 1, _sheetRefIndex);
|
||||
LittleEndian.putUShort(array, offset + 3, _nameNumber);
|
||||
LittleEndian.putUShort(array, offset + 5, _reserved);
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
// -1 to convert definedNameIndex from 1-based to zero-based
|
||||
return book.resolveNameXText(_sheetRefIndex, _nameNumber - 1);
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_VALUE;
|
||||
}
|
||||
}
|
||||
|
@ -22,67 +22,57 @@ import org.apache.poi.hssf.record.NameRecord;
|
||||
import org.apache.poi.hssf.util.RangeAddress;
|
||||
|
||||
/**
|
||||
* Title: High Level Represantion of Named Range <P>
|
||||
* REFERENCE: <P>
|
||||
* High Level Representation of a 'defined name' which could be a 'built-in' name,
|
||||
* 'named range' or name of a user defined function.
|
||||
*
|
||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||
*/
|
||||
|
||||
public class HSSFName {
|
||||
private HSSFWorkbook book;
|
||||
private NameRecord name;
|
||||
public final class HSSFName {
|
||||
private HSSFWorkbook _book;
|
||||
private NameRecord _definedNameRec;
|
||||
|
||||
/** Creates new HSSFName - called by HSSFWorkbook to create a sheet from
|
||||
* scratch.
|
||||
*
|
||||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createName()
|
||||
* @param name the Name Record
|
||||
* @param book lowlevel Workbook object associated with the sheet.
|
||||
* @param book workbook object associated with the sheet.
|
||||
*/
|
||||
|
||||
protected HSSFName(HSSFWorkbook book, NameRecord name) {
|
||||
this.book = book;
|
||||
this.name = name;
|
||||
/* package */ HSSFName(HSSFWorkbook book, NameRecord name) {
|
||||
_book = book;
|
||||
_definedNameRec = name;
|
||||
}
|
||||
|
||||
/** Get the sheets name which this named range is referenced to
|
||||
* @return sheet name, which this named range refered to
|
||||
* @return sheet name, which this named range referred to
|
||||
*/
|
||||
|
||||
public String getSheetName() {
|
||||
String result ;
|
||||
short indexToExternSheet = name.getExternSheetNumber();
|
||||
short indexToExternSheet = _definedNameRec.getExternSheetNumber();
|
||||
|
||||
result = book.getWorkbook().findSheetNameFromExternSheet(indexToExternSheet);
|
||||
|
||||
return result;
|
||||
return _book.getWorkbook().findSheetNameFromExternSheet(indexToExternSheet);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the name of the named range
|
||||
* @return named range name
|
||||
* @return text name of this defined name
|
||||
*/
|
||||
|
||||
public String getNameName(){
|
||||
String result = name.getNameText();
|
||||
|
||||
return result;
|
||||
return _definedNameRec.getNameText();
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the name of the named range
|
||||
* @param nameName named range name to set
|
||||
*/
|
||||
|
||||
public void setNameName(String nameName){
|
||||
name.setNameText(nameName);
|
||||
name.setNameTextLength((byte)nameName.length());
|
||||
Workbook wb = book.getWorkbook();
|
||||
_definedNameRec.setNameText(nameName);
|
||||
_definedNameRec.setNameTextLength((byte)nameName.length());
|
||||
Workbook wb = _book.getWorkbook();
|
||||
|
||||
//Check to ensure no other names have the same case-insensitive name
|
||||
for ( int i = wb.getNumNames()-1; i >=0; i-- )
|
||||
{
|
||||
NameRecord rec = wb.getNameRecord(i);
|
||||
if (rec != name) {
|
||||
if (rec != _definedNameRec) {
|
||||
if (rec.getNameText().equalsIgnoreCase(getNameName()))
|
||||
throw new IllegalArgumentException("The workbook already contains this name (case-insensitive)");
|
||||
}
|
||||
@ -90,31 +80,24 @@ public class HSSFName {
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the reference of the named range
|
||||
* @return reference of the named range
|
||||
* Note - this method only applies to named ranges
|
||||
* @return the formula text defining the named range
|
||||
*/
|
||||
|
||||
public String getReference() {
|
||||
String result;
|
||||
result = name.getAreaReference(book);
|
||||
|
||||
return result;
|
||||
if (_definedNameRec.isFunctionName()) {
|
||||
throw new IllegalStateException("Only applicable to named ranges");
|
||||
}
|
||||
return _definedNameRec.getAreaReference(_book);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* sets the sheet name which this named range referenced to
|
||||
* @param sheetName the sheet name of the reference
|
||||
*/
|
||||
|
||||
private void setSheetName(String sheetName){
|
||||
int sheetNumber = book.getSheetIndex(sheetName);
|
||||
|
||||
short externSheetNumber = book.getExternalSheetIndex(sheetNumber);
|
||||
name.setExternSheetNumber(externSheetNumber);
|
||||
// name.setIndexToSheet(externSheetNumber);
|
||||
|
||||
int sheetNumber = _book.getSheetIndex(sheetName);
|
||||
short externSheetNumber = _book.getExternalSheetIndex(sheetNumber);
|
||||
_definedNameRec.setExternSheetNumber(externSheetNumber);
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +105,6 @@ public class HSSFName {
|
||||
* sets the reference of this named range
|
||||
* @param ref the reference to set
|
||||
*/
|
||||
|
||||
public void setReference(String ref){
|
||||
|
||||
RangeAddress ra = new RangeAddress(ref);
|
||||
@ -134,8 +116,7 @@ public class HSSFName {
|
||||
}
|
||||
|
||||
//allow the poi utilities to parse it out
|
||||
name.setAreaReference(ref);
|
||||
|
||||
_definedNameRec.setAreaReference(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,4 +128,14 @@ public class HSSFName {
|
||||
String ref = getReference();
|
||||
return "#REF!".endsWith(ref);
|
||||
}
|
||||
public boolean isFunctionName() {
|
||||
return _definedNameRec.isFunctionName();
|
||||
}
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append(getClass().getName()).append(" [");
|
||||
sb.append(_definedNameRec.getNameText());
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -17,24 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.POIDocument;
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.ddf.EscherBitmapBlip;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.EscherBlipRecord;
|
||||
import org.apache.poi.hssf.model.Sheet;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
import org.apache.poi.hssf.record.formula.MemFuncPtg;
|
||||
import org.apache.poi.hssf.record.formula.UnionPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.poifs.filesystem.*;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@ -47,6 +29,40 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.POIDocument;
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.ddf.EscherBitmapBlip;
|
||||
import org.apache.poi.ddf.EscherBlipRecord;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.hssf.model.Sheet;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.AbstractEscherHolderRecord;
|
||||
import org.apache.poi.hssf.record.BackupRecord;
|
||||
import org.apache.poi.hssf.record.DrawingGroupRecord;
|
||||
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
||||
import org.apache.poi.hssf.record.ExtendedFormatRecord;
|
||||
import org.apache.poi.hssf.record.FontRecord;
|
||||
import org.apache.poi.hssf.record.LabelRecord;
|
||||
import org.apache.poi.hssf.record.LabelSSTRecord;
|
||||
import org.apache.poi.hssf.record.NameRecord;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RecordFactory;
|
||||
import org.apache.poi.hssf.record.SSTRecord;
|
||||
import org.apache.poi.hssf.record.UnicodeString;
|
||||
import org.apache.poi.hssf.record.UnknownRecord;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
import org.apache.poi.hssf.record.formula.MemFuncPtg;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
import org.apache.poi.hssf.record.formula.UnionPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* High level representation of a workbook. This is the first object most users
|
||||
* will construct whether they are reading or writing a workbook. It is also the
|
||||
@ -1640,9 +1656,16 @@ public class HSSFWorkbook extends POIDocument
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] newUID()
|
||||
{
|
||||
byte[] bytes = new byte[16];
|
||||
return bytes;
|
||||
private static byte[] newUID() {
|
||||
return new byte[16];
|
||||
}
|
||||
|
||||
/**
|
||||
* Note - This method should only used by POI internally.
|
||||
* It may get deleted or change definition in future POI versions
|
||||
*/
|
||||
public NameXPtg getNameXPtg(String name) {
|
||||
return workbook.getNameXPtg(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/testNames.xls
Normal file
BIN
src/testcases/org/apache/poi/hssf/data/testNames.xls
Normal file
Binary file not shown.
@ -20,6 +20,7 @@ package org.apache.poi.hssf.model;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.FormulaParser.FormulaParseException;
|
||||
import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
|
||||
import org.apache.poi.hssf.record.formula.AddPtg;
|
||||
@ -123,12 +124,15 @@ public final class TestFormulaParser extends TestCase {
|
||||
}
|
||||
|
||||
public void testMacroFunction() {
|
||||
HSSFWorkbook w = new HSSFWorkbook();
|
||||
Ptg[] ptg = FormulaParser.parse("FOO()", w);
|
||||
// testNames.xls contains a VB function called 'myFunc'
|
||||
HSSFWorkbook w = HSSFTestDataSamples.openSampleWorkbook("testNames.xls");
|
||||
|
||||
Ptg[] ptg = FormulaParser.parse("myFunc()", w);
|
||||
// myFunc() actually takes 1 parameter. Don't know if POI will ever be able to detect this problem
|
||||
|
||||
// the name gets encoded as the first arg
|
||||
NamePtg tname = (NamePtg) ptg[0];
|
||||
assertEquals("FOO", tname.toFormulaString(w));
|
||||
assertEquals("myFunc", tname.toFormulaString(w));
|
||||
|
||||
AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[1];
|
||||
assertTrue(tfunc.isExternalFunction());
|
||||
|
@ -17,11 +17,19 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.FormulaParser;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
|
||||
/**
|
||||
* Tests for functions from external workbooks (e.g. YEARFRAC).
|
||||
*
|
||||
@ -30,17 +38,45 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
*/
|
||||
public final class TestExternalFunctionFormulas extends TestCase {
|
||||
|
||||
|
||||
/**
|
||||
* tests <tt>NameXPtg.toFormulaString(Workbook)</tt> and logic in Workbook below that
|
||||
*/
|
||||
public void testReadFormulaContainingExternalFunction() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
|
||||
|
||||
String expectedFormula = "YEARFRAC(B1,C1)";
|
||||
HSSFSheet sht = wb.getSheetAt(0);
|
||||
String cellFormula = sht.getRow(0).getCell((short)0).getCellFormula();
|
||||
assertEquals(expectedFormula, cellFormula);
|
||||
}
|
||||
|
||||
/**
|
||||
* tests <tt>NameXPtg.toFormulaString(Workbook)</tt> and logic in Workbook below that
|
||||
*/
|
||||
public void testReadFormulaContainingExternalFunction() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
|
||||
|
||||
String expectedFormula = "YEARFRAC(B1,C1)";
|
||||
HSSFSheet sht = wb.getSheetAt(0);
|
||||
String cellFormula = sht.getRow(0).getCell(0).getCellFormula();
|
||||
assertEquals(expectedFormula, cellFormula);
|
||||
}
|
||||
|
||||
public void testParse() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
|
||||
Ptg[] ptgs = FormulaParser.parse("YEARFRAC(B1,C1)", wb);
|
||||
assertEquals(4, ptgs.length);
|
||||
assertEquals(NameXPtg.class, ptgs[0].getClass());
|
||||
|
||||
wb.getSheetAt(0).getRow(0).createCell(6).setCellFormula("YEARFRAC(C1,B1)");
|
||||
if (false) {
|
||||
// In case you fancy checking in excel
|
||||
try {
|
||||
File tempFile = File.createTempFile("testExtFunc", ".xls");
|
||||
FileOutputStream fout = new FileOutputStream(tempFile);
|
||||
wb.write(fout);
|
||||
fout.close();
|
||||
System.out.println("check out " + tempFile.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DISABLEDtestEvaluate() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
|
||||
HSSFSheet sheet = wb.getSheetAt(0);
|
||||
HSSFCell cell = sheet.getRow(0).getCell(0);
|
||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
|
||||
CellValue evalResult = fe.evaluate(cell);
|
||||
evalResult.toString();
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,11 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
@ -34,20 +37,33 @@ public final class TestExternalFunction extends TestCase {
|
||||
|
||||
/**
|
||||
* Checks that an external function can get invoked from the formula evaluator.
|
||||
* @throws IOException
|
||||
|
||||
*/
|
||||
public void testInvoke() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell(0);
|
||||
|
||||
HSSFName hssfName = wb.createName();
|
||||
hssfName.setNameName("myFunc");
|
||||
|
||||
cell.setCellFormula("myFunc()");
|
||||
String actualFormula=cell.getCellFormula();
|
||||
assertEquals("myFunc()", actualFormula);
|
||||
|
||||
HSSFWorkbook wb;
|
||||
HSSFSheet sheet;
|
||||
HSSFCell cell;
|
||||
if (false) {
|
||||
// TODO - this code won't work until we can create user-defined functions directly with POI
|
||||
wb = new HSSFWorkbook();
|
||||
sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
HSSFName hssfName = wb.createName();
|
||||
hssfName.setNameName("myFunc");
|
||||
|
||||
} else {
|
||||
// This sample spreadsheet already has a VB function called 'myFunc'
|
||||
wb = HSSFTestDataSamples.openSampleWorkbook("testNames.xls");
|
||||
sheet = wb.getSheetAt(0);
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
cell = row.createCell(1);
|
||||
}
|
||||
|
||||
cell.setCellFormula("myFunc()");
|
||||
String actualFormula=cell.getCellFormula();
|
||||
assertEquals("myFunc()", actualFormula);
|
||||
|
||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
|
||||
CellValue evalResult = fe.evaluate(cell);
|
||||
|
@ -415,6 +415,9 @@ public final class TestBugs extends TestCase {
|
||||
for(int i = 0 ; i < wb.getNumberOfNames(); i++){
|
||||
HSSFName name = wb.getNameAt(i);
|
||||
name.getNameName();
|
||||
if (name.isFunctionName()) {
|
||||
continue;
|
||||
}
|
||||
name.getReference();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user