diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index d45153f9c9..a6ab7af382 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -85,62 +85,75 @@ import org.apache.poi.util.POILogFactory; * @version 1.0-pre */ -public class Workbook -{ +public class Workbook { private static final int DEBUG = POILogger.DEBUG; - + /** * constant used to set the "codepage" wherever "codepage" is set in records * (which is duplciated in more than one record) */ - + private final static short CODEPAGE = ( short ) 0x4b0; - + /** * this contains the Worksheet record objects */ - + protected ArrayList records = null; - + /** * this contains a reference to the SSTRecord so that new stings can be added * to it. */ - + protected SSTRecord sst = null; - + + /** + * Holds the Extern Sheet with referenced to bound sheets + */ + + protected ExternSheetRecord externSheet= null; + /** * holds the "boundsheet" records (aka bundlesheet) so that they can have their * reference to their "BOF" marker */ - + + protected ArrayList boundsheets = new ArrayList(); + + protected ArrayList names = new ArrayList(); + protected int bspos = - 0; // holds the position of the last bound sheet. + 0; // holds the position of the last bound sheet. protected int tabpos = - 0; // holds the position of the tabid record + 0; // holds the position of the tabid record protected int fontpos = - 0; // hold the position of the last font record + 0; // hold the position of the last font record protected int numfonts = - 0; // hold the number of font records + 0; // hold the number of font records protected int xfpos = - 0; // hold the position of the last extended font record + 0; // hold the position of the last extended font record protected int numxfs = - 0; // hold the number of extended format records + 0; // hold the number of extended format records private int backuppos = - 0; // holds the position of the backup record. + 0; // holds the position of the backup record. + private int namepos = + 0; // holds the position of last name record + private int supbookpos = + 0; // holds the position of sup book + private static POILogger log = - POILogFactory.getLogger(Workbook.class); - + POILogFactory.getLogger(Workbook.class); + /** * Creates new Workbook with no intitialization --useless right now * @see #createWorkbook(List) */ - - public Workbook() - { + + public Workbook() { } - + /** * read support for low level * API. Pass in an array of Record objects, A Workbook @@ -153,80 +166,96 @@ public class Workbook * @param recs an array of Record objects * @return Workbook object */ - - public static Workbook createWorkbook(List recs) - { + + public static Workbook createWorkbook(List recs) { log.log(DEBUG, "Workbook (readfile) created with reclen=", - new Integer(recs.size())); + new Integer(recs.size())); Workbook retval = new Workbook(); ArrayList records = new ArrayList(recs.size() / 3); - - for (int k = 0; k < recs.size(); k++) - { + + for (int k = 0; k < recs.size(); k++) { Record rec = ( Record ) recs.get(k); - - if (rec.getSid() == EOFRecord.sid) - { + + if (rec.getSid() == EOFRecord.sid) { records.add(rec); log.log(DEBUG, "found workbook eof record at " + k); break; } - switch (rec.getSid()) - { - + switch (rec.getSid()) { + case BoundSheetRecord.sid : log.log(DEBUG, "found boundsheet record at " + k); retval.boundsheets.add(rec); retval.bspos = k; break; - + case SSTRecord.sid : log.log(DEBUG, "found sst record at " + k); retval.sst = ( SSTRecord ) rec; break; - + case FontRecord.sid : log.log(DEBUG, "found font record at " + k); retval.fontpos = k; retval.numfonts++; break; - + case ExtendedFormatRecord.sid : log.log(DEBUG, "found XF record at " + k); retval.xfpos = k; retval.numxfs++; break; - + case TabIdRecord.sid : log.log(DEBUG, "found tabid record at " + k); retval.tabpos = k; break; - + case BackupRecord.sid : log.log(DEBUG, "found backup record at " + k); retval.backuppos = k; break; - + case ExternSheetRecord.sid : + log.log(DEBUG, "found extern sheet record at " + k); + retval.externSheet = ( ExternSheetRecord ) rec; + break; + case NameRecord.sid : + log.log(DEBUG, "found name record at " + k); + retval.names.add(rec); + retval.namepos = k; + break; + case 0x1AE : + //Havent Implement the sup book , because we dont need extern ranges + //for now + log.log(DEBUG, "found SupBook record at " + k); + retval.supbookpos = k; + break; + default : } records.add(rec); } + //What if we dont have any ranges and supbooks + if (retval.supbookpos == 0) { + retval.supbookpos = retval.bspos + 1; + retval.namepos = retval.supbookpos + 1; + } + retval.records = records; log.log(DEBUG, "exit create workbook from existing file function"); return retval; } - + /** * Creates an empty workbook object with three blank sheets and all the empty * fields. Use this to create a workbook from scratch. */ - - public static Workbook createWorkbook() - { + + public static Workbook createWorkbook() { log.log(DEBUG, "creating new workbook from scratch"); Workbook retval = new Workbook(); ArrayList records = new ArrayList(30); - + records.add(retval.createBOF()); records.add(retval.createInterfaceHdr()); records.add(retval.createMMS()); @@ -264,22 +293,19 @@ public class Workbook records.add(retval.createFormat(5)); records.add(retval.createFormat(6)); records.add(retval.createFormat(7)); - for (int k = 0; k < 21; k++) - { + for (int k = 0; k < 21; k++) { records.add(retval.createExtendedFormat(k)); retval.numxfs++; } retval.xfpos = records.size() - 1; - for (int k = 0; k < 6; k++) - { + for (int k = 0; k < 6; k++) { records.add(retval.createStyle(k)); } records.add(retval.createUseSelFS()); - for (int k = 0; k < 1; k++) - { // now just do 1 + for (int k = 0; k < 1; k++) { // now just do 1 BoundSheetRecord bsr = - ( BoundSheetRecord ) retval.createBoundSheet(k); - + ( BoundSheetRecord ) retval.createBoundSheet(k); + records.add(bsr); retval.boundsheets.add(bsr); retval.bspos = records.size() - 1; @@ -288,19 +314,18 @@ public class Workbook retval.sst = ( SSTRecord ) retval.createSST(); records.add(retval.sst); records.add(retval.createExtendedSST()); - + // TODO records.add(retval.createEOF()); retval.records = records; log.log(DEBUG, "exit create new workbook from scratch"); return retval; } - - public int getNumRecords() - { + + public int getNumRecords() { return records.size(); } - + /** * gets the font record at the given index in the font table. Remember * "There is No Four" (someone at M$ must have gone to Rocky Horror one too @@ -309,27 +334,24 @@ public class Workbook * @param idx the index to look at (0 or greater but NOT 4) * @return FontRecord located at the given index */ - - public FontRecord getFontRecordAt(int idx) - { + + public FontRecord getFontRecordAt(int idx) { int index = idx; - - if (index > 4) - { + + if (index > 4) { index -= 1; // adjust for "There is no 4" } - if (index > (numfonts - 1)) - { + if (index > (numfonts - 1)) { throw new ArrayIndexOutOfBoundsException( - "There are only " + numfonts - + " font records, you asked for " + idx); + "There are only " + numfonts + + " font records, you asked for " + idx); } FontRecord retval = - ( FontRecord ) records.get((fontpos - (numfonts - 1)) + index); - + ( FontRecord ) records.get((fontpos - (numfonts - 1)) + index); + return retval; } - + /** * creates a new font record and adds it to the "font table". This causes the * boundsheets to move down one, extended formats to move down (so this function moves @@ -337,11 +359,10 @@ public class Workbook * * @return FontRecord that was just created */ - - public FontRecord createNewFont() - { + + public FontRecord createNewFont() { FontRecord rec = ( FontRecord ) createFont(); - + ++fontpos; ++bspos; ++xfpos; @@ -349,43 +370,40 @@ public class Workbook numfonts++; return rec; } - + /** * gets the number of font records * * @return number of font records in the "font table" */ - - public int getNumberOfFontRecords() - { + + public int getNumberOfFontRecords() { return numfonts; } - + /** * Sets the BOF for a given sheet * * @param sheetnum 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 sheetnum, int pos) { log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetnum), - " at pos=", new Integer(pos)); + " at pos=", new Integer(pos)); checkSheets(sheetnum); (( BoundSheetRecord ) boundsheets.get(sheetnum)) - .setPositionOfBof(pos); + .setPositionOfBof(pos); } - + /** * Returns the position of the backup record. */ - - public BackupRecord getBackupRecord() - { + + public BackupRecord getBackupRecord() { return ( BackupRecord ) records.get(backuppos); } - + /** * sets the name for a given sheet. If the boundsheet record doesn't exist and * its only one more than we have, go ahead and create it. If its > 1 more than @@ -394,139 +412,146 @@ public class Workbook * @param sheetnum the sheet number (0 based) * @param sheetname the name for the sheet */ - - public void setSheetName(int sheetnum, String sheetname) - { + + public void setSheetName(int sheetnum, String sheetname) { checkSheets(sheetnum); (( BoundSheetRecord ) boundsheets.get(sheetnum)) - .setSheetname(sheetname); + .setSheetname(sheetname); (( BoundSheetRecord ) boundsheets.get(sheetnum)) - .setSheetnameLength(( byte ) sheetname.length()); + .setSheetnameLength(( byte ) sheetname.length()); } - + /** * gets the name for a given sheet. * * @param sheetnum the sheet number (0 based) * @return sheetname the name for the sheet */ - - public String getSheetName(int sheetnum) - { + + public String getSheetName(int sheetnum) { return (( BoundSheetRecord ) boundsheets.get(sheetnum)) - .getSheetname(); + .getSheetname(); } - + + /** + * get the sheet's index + * @param name sheet name + * @return sheet index or -1 if it was not found. + */ + + public int getSheetIndex(String name) { + int retval = -1; + + for (int k = 0; k < boundsheets.size(); k++) { + String sheet = getSheetName(k); + + if (sheet.equals(name)) { + retval = k; + break; + } + } + return retval; + } + /** * if we're trying to address one more sheet than we have, go ahead and add it! if we're * trying to address >1 more than we have throw an exception! */ - - private void checkSheets(int sheetnum) - { - if ((boundsheets.size()) <= sheetnum) - { // if we're short one add another.. - if ((boundsheets.size() + 1) <= sheetnum) - { + + private void checkSheets(int sheetnum) { + if ((boundsheets.size()) <= sheetnum) { // if we're short one add another.. + if ((boundsheets.size() + 1) <= sheetnum) { throw new RuntimeException("Sheet number out of bounds!"); } BoundSheetRecord bsr = - ( BoundSheetRecord ) createBoundSheet(sheetnum); - + ( BoundSheetRecord ) createBoundSheet(sheetnum); + records.add(++bspos, bsr); boundsheets.add(bsr); fixTabIdRecord(); } } - - public void removeSheet(int sheetnum) - { - if (boundsheets.size() > sheetnum) - { + + public void removeSheet(int sheetnum) { + if (boundsheets.size() > sheetnum) { records.remove(bspos - (boundsheets.size() - 1) + sheetnum); bspos--; boundsheets.remove(sheetnum); fixTabIdRecord(); } } - + /** * make the tabid record look like the current situation. * */ - - private void fixTabIdRecord() - { + + private void fixTabIdRecord() { TabIdRecord tir = ( TabIdRecord ) records.get(tabpos); short[] tia = new short[ boundsheets.size() ]; - - for (short k = 0; k < tia.length; k++) - { + + for (short k = 0; k < tia.length; k++) { tia[ k ] = k; } tir.setTabIdArray(tia); } - + /** * returns the number of boundsheet objects contained in this workbook. * * @return number of BoundSheet records */ - - public int getNumSheets() - { + + public int getNumSheets() { log.log(DEBUG, "getNumSheets=", new Integer(boundsheets.size())); return boundsheets.size(); } - + /** * get the number of ExtendedFormat records contained in this workbook. * * @return int count of ExtendedFormat records */ - - public int getNumExFormats() - { + + public int getNumExFormats() { log.log(DEBUG, "getXF=", new Integer(boundsheets.size())); return numxfs; } - + /** * gets the ExtendedFormatRecord at the given 0-based index * * @param index of the Extended format record (0-based) * @return ExtendedFormatRecord at the given index */ - - public ExtendedFormatRecord getExFormatAt(int index) - { + + public ExtendedFormatRecord getExFormatAt(int index) { int xfptr = xfpos - (numxfs - 1); - + xfptr += index; ExtendedFormatRecord retval = - ( ExtendedFormatRecord ) records.get(xfptr); - + ( ExtendedFormatRecord ) records.get(xfptr); + return retval; } - + /** * creates a new Cell-type Extneded Format Record and adds it to the end of * ExtendedFormatRecords collection * * @return ExtendedFormatRecord that was created */ - - public ExtendedFormatRecord createCellXF() - { + + public ExtendedFormatRecord createCellXF() { ExtendedFormatRecord xf = createExtendedFormat(); - + ++xfpos; ++bspos; records.add(xfpos, xf); numxfs++; return xf; } - + /** * Adds a string to the SST table and returns its index (if its a duplicate * just returns its index and update the counts) @@ -535,18 +560,16 @@ public class Workbook * @param use16bits whether to use utf 16 or false for compressed unicode * @return index of the string within the SSTRecord */ - - public int addSSTString(String string, boolean use16bits) - { + + public int addSSTString(String string, boolean use16bits) { log.log(DEBUG, "insert to sst string='", string, "' and use16bits= ", - new Boolean(use16bits)); - if (sst == null) - { + new Boolean(use16bits)); + if (sst == null) { insertSST(); } return sst.addString(string, use16bits); } - + /** * Adds a string to the SST table and returns its index (if its a duplicate * just returns its index and update the counts) ASSUMES compressed unicode @@ -556,240 +579,223 @@ public class Workbook * * @return index of the string within the SSTRecord */ - - public int addSSTString(String string) - { + + public int addSSTString(String string) { return addSSTString(string, false); } - + /** * given an index into the SST table, this function returns the corresponding String value * @return String containing the SST String */ - - public String getSSTString(int str) - { - if (sst == null) - { + + public String getSSTString(int str) { + if (sst == null) { insertSST(); } String retval = sst.getString(str); - + log.log(DEBUG, "Returning SST for index=", new Integer(str), - " String= ", retval); + " String= ", retval); return retval; } - + /** * use this function to add a Shared String Table to an existing sheet (say * generated by a different java api) without an sst.... * @see #createSST() * @see org.apache.poi.hssf.record.SSTRecord */ - - public void insertSST() - { + + public void insertSST() { log.log(DEBUG, "creating new SST via insertSST!"); sst = ( SSTRecord ) createSST(); records.add(records.size() - 1, createExtendedSST()); records.add(records.size() - 2, sst); } - + /** * Serializes all records int the worksheet section into a big byte array. Use * this to write the Workbook out. * * @return byte array containing the HSSF-only portions of the POIFS file. */ - - public byte [] serialize() - { + + public byte [] serialize() { log.log(DEBUG, "Serializing Workbook!"); byte[] retval = null; - + // ArrayList bytes = new ArrayList(records.size()); int arraysize = getSize(); int pos = 0; - + // for (int k = 0; k < records.size(); k++) // { // bytes.add((( Record ) records.get(k)).serialize()); -// } + // } // for (int k = 0; k < bytes.size(); k++) // { // arraysize += (( byte [] ) bytes.get(k)).length; // } retval = new byte[ arraysize ]; - for (int k = 0; k < records.size(); k++) - { - + for (int k = 0; k < records.size(); k++) { + // byte[] rec = (( byte [] ) bytes.get(k)); // System.arraycopy(rec, 0, retval, pos, rec.length); pos += (( Record ) records.get(k)).serialize(pos, - retval); // rec.length; + retval); // rec.length; } log.log(DEBUG, "Exiting serialize workbook"); return retval; } - + /** * Serializes all records int the worksheet section into a big byte array. Use * this to write the Workbook out. * @param offset of the data to be written * @param data array of bytes to write this to */ - - public int serialize(int offset, byte [] data) - { + + public int serialize(int offset, byte [] data) { log.log(DEBUG, "Serializing Workbook with offsets"); - + // ArrayList bytes = new ArrayList(records.size()); -// int arraysize = getSize(); // 0; + // int arraysize = getSize(); // 0; int pos = 0; - -// for (int k = 0; k < records.size(); k++) -// { -// bytes.add((( Record ) records.get(k)).serialize()); -// -// } -// for (int k = 0; k < bytes.size(); k++) -// { -// arraysize += (( byte [] ) bytes.get(k)).length; -// } - for (int k = 0; k < records.size(); k++) - { - + + // for (int k = 0; k < records.size(); k++) + // { + // bytes.add((( Record ) records.get(k)).serialize()); + // + // } + // for (int k = 0; k < bytes.size(); k++) + // { + // arraysize += (( byte [] ) bytes.get(k)).length; + // } + for (int k = 0; k < records.size(); k++) { + // byte[] rec = (( byte [] ) bytes.get(k)); // System.arraycopy(rec, 0, data, offset + pos, rec.length); pos += (( Record ) records.get(k)).serialize(pos + offset, - data); // rec.length; + data); // rec.length; } log.log(DEBUG, "Exiting serialize workbook"); return pos; } - - public int getSize() - { + + public int getSize() { int retval = 0; - - for (int k = 0; k < records.size(); k++) - { + + for (int k = 0; k < records.size(); k++) { retval += (( Record ) records.get(k)).getRecordSize(); } return retval; } - + /** * creates the BOF record * @see org.apache.poi.hssf.record.BOFRecord * @see org.apache.poi.hssf.record.Record * @return record containing a BOFRecord */ - - protected Record createBOF() - { + + protected Record createBOF() { BOFRecord retval = new BOFRecord(); - + retval.setVersion(( short ) 0x600); retval.setType(( short ) 5); retval.setBuild(( short ) 0x10d3); - -// retval.setBuild((short)0x0dbb); + + // retval.setBuild((short)0x0dbb); retval.setBuildYear(( short ) 1996); retval.setHistoryBitMask(0x41); // was c1 before verify retval.setRequiredVersion(0x6); return retval; } - + /** * creates the InterfaceHdr record * @see org.apache.poi.hssf.record.InterfaceHdrRecord * @see org.apache.poi.hssf.record.Record * @return record containing a InterfaceHdrRecord */ - - protected Record createInterfaceHdr() - { + + protected Record createInterfaceHdr() { InterfaceHdrRecord retval = new InterfaceHdrRecord(); - + retval.setCodepage(CODEPAGE); return retval; } - + /** * creates an MMS record * @see org.apache.poi.hssf.record.MMSRecord * @see org.apache.poi.hssf.record.Record * @return record containing a MMSRecord */ - - protected Record createMMS() - { + + protected Record createMMS() { MMSRecord retval = new MMSRecord(); - + retval.setAddMenuCount(( byte ) 0); retval.setDelMenuCount(( byte ) 0); return retval; } - + /** * creates the InterfaceEnd record * @see org.apache.poi.hssf.record.InterfaceEndRecord * @see org.apache.poi.hssf.record.Record * @return record containing a InterfaceEndRecord */ - - protected Record createInterfaceEnd() - { + + protected Record createInterfaceEnd() { return new InterfaceEndRecord(); } - + /** * creates the WriteAccess record containing the logged in user's name * @see org.apache.poi.hssf.record.WriteAccessRecord * @see org.apache.poi.hssf.record.Record * @return record containing a WriteAccessRecord */ - - protected Record createWriteAccess() - { + + protected Record createWriteAccess() { WriteAccessRecord retval = new WriteAccessRecord(); - + retval.setUsername(System.getProperty("user.name")); return retval; } - + /** * creates the Codepage record containing the constant stored in CODEPAGE * @see org.apache.poi.hssf.record.CodepageRecord * @see org.apache.poi.hssf.record.Record * @return record containing a CodepageRecord */ - - protected Record createCodepage() - { + + protected Record createCodepage() { CodepageRecord retval = new CodepageRecord(); - + retval.setCodepage(CODEPAGE); return retval; } - + /** * creates the DSF record containing a 0 since HSSF can't even create Dual Stream Files * @see org.apache.poi.hssf.record.DSFRecord * @see org.apache.poi.hssf.record.Record * @return record containing a DSFRecord */ - - protected Record createDSF() - { + + protected Record createDSF() { DSFRecord retval = new DSFRecord(); - + retval.setDsf( - ( short ) 0); // we don't even support double stream files + ( short ) 0); // we don't even support double stream files return retval; } - + /** * creates the TabId record containing an array of 0,1,2. This release of HSSF * always has the default three sheets, no less, no more. @@ -797,111 +803,103 @@ public class Workbook * @see org.apache.poi.hssf.record.Record * @return record containing a TabIdRecord */ - - protected Record createTabId() - { + + protected Record createTabId() { TabIdRecord retval = new TabIdRecord(); - short[] tabidarray = - { + short[] tabidarray = { 0 }; - + retval.setTabIdArray(tabidarray); return retval; } - + /** * creates the FnGroupCount record containing the Magic number constant of 14. * @see org.apache.poi.hssf.record.FnGroupCountRecord * @see org.apache.poi.hssf.record.Record * @return record containing a FnGroupCountRecord */ - - protected Record createFnGroupCount() - { + + protected Record createFnGroupCount() { FnGroupCountRecord retval = new FnGroupCountRecord(); - + retval.setCount(( short ) 14); return retval; } - + /** * creates the WindowProtect record with protect set to false. * @see org.apache.poi.hssf.record.WindowProtectRecord * @see org.apache.poi.hssf.record.Record * @return record containing a WindowProtectRecord */ - - protected Record createWindowProtect() - { + + protected Record createWindowProtect() { WindowProtectRecord retval = new WindowProtectRecord(); - + retval.setProtect( - false); // by default even when we support it we won't + false); // by default even when we support it we won't return retval; // want it to be protected } - + /** * creates the Protect record with protect set to false. * @see org.apache.poi.hssf.record.ProtectRecord * @see org.apache.poi.hssf.record.Record * @return record containing a ProtectRecord */ - - protected Record createProtect() - { + + protected Record createProtect() { ProtectRecord retval = new ProtectRecord(); - + retval.setProtect( - false); // by default even when we support it we won't + false); // by default even when we support it we won't return retval; // want it to be protected } - + /** * creates the Password record with password set to 0. * @see org.apache.poi.hssf.record.PasswordRecord * @see org.apache.poi.hssf.record.Record * @return record containing a PasswordRecord */ - - protected Record createPassword() - { + + protected Record createPassword() { PasswordRecord retval = new PasswordRecord(); - + retval.setPassword(( short ) 0); // no password by default! return retval; } - + /** * creates the ProtectionRev4 record with protect set to false. * @see org.apache.poi.hssf.record.ProtectionRev4Record * @see org.apache.poi.hssf.record.Record * @return record containing a ProtectionRev4Record */ - - protected Record createProtectionRev4() - { + + protected Record createProtectionRev4() { ProtectionRev4Record retval = new ProtectionRev4Record(); - + retval.setProtect(false); return retval; } - + /** * creates the PasswordRev4 record with password set to 0. * @see org.apache.poi.hssf.record.PasswordRev4Record * @see org.apache.poi.hssf.record.Record * @return record containing a PasswordRev4Record */ - - protected Record createPasswordRev4() - { + + protected Record createPasswordRev4() { PasswordRev4Record retval = new PasswordRev4Record(); - + retval.setPassword(( short ) 0); // no password by default! return retval; } - + /** * creates the WindowOne record with the following magic values:
* horizontal hold - 0x168
@@ -917,11 +915,10 @@ public class Workbook * @see org.apache.poi.hssf.record.Record * @return record containing a WindowOneRecord */ - - protected Record createWindowOne() - { + + protected Record createWindowOne() { WindowOneRecord retval = new WindowOneRecord(); - + retval.setHorizontalHold(( short ) 0x168); retval.setVerticalHold(( short ) 0x10e); retval.setWidth(( short ) 0x3a5c); @@ -933,100 +930,94 @@ public class Workbook retval.setTabWidthRatio(( short ) 0x258); return retval; } - + /** * creates the Backup record with backup set to 0. (loose the data, who cares) * @see org.apache.poi.hssf.record.BackupRecord * @see org.apache.poi.hssf.record.Record * @return record containing a BackupRecord */ - - protected Record createBackup() - { + + protected Record createBackup() { BackupRecord retval = new BackupRecord(); - + retval.setBackup( - ( short ) 0); // by default DONT save backups of files...just loose data + ( short ) 0); // by default DONT save backups of files...just loose data return retval; } - + /** * creates the HideObj record with hide object set to 0. (don't hide) * @see org.apache.poi.hssf.record.HideObjRecord * @see org.apache.poi.hssf.record.Record * @return record containing a HideObjRecord */ - - protected Record createHideObj() - { + + protected Record createHideObj() { HideObjRecord retval = new HideObjRecord(); - + retval.setHideObj(( short ) 0); // by default set hide object off return retval; } - + /** * creates the DateWindow1904 record with windowing set to 0. (don't window) * @see org.apache.poi.hssf.record.DateWindow1904Record * @see org.apache.poi.hssf.record.Record * @return record containing a DateWindow1904Record */ - - protected Record createDateWindow1904() - { + + protected Record createDateWindow1904() { DateWindow1904Record retval = new DateWindow1904Record(); - + retval.setWindowing( - ( short ) 0); // don't EVER use 1904 date windowing...tick tock.. + ( short ) 0); // don't EVER use 1904 date windowing...tick tock.. return retval; } - + /** * creates the Precision record with precision set to true. (full precision) * @see org.apache.poi.hssf.record.PrecisionRecord * @see org.apache.poi.hssf.record.Record * @return record containing a PrecisionRecord */ - - protected Record createPrecision() - { + + protected Record createPrecision() { PrecisionRecord retval = new PrecisionRecord(); - + retval.setFullPrecision( - true); // always use real numbers in calculations! + true); // always use real numbers in calculations! return retval; } - + /** * creates the RefreshAll record with refreshAll set to true. (refresh all calcs) * @see org.apache.poi.hssf.record.RefreshAllRecord * @see org.apache.poi.hssf.record.Record * @return record containing a RefreshAllRecord */ - - protected Record createRefreshAll() - { + + protected Record createRefreshAll() { RefreshAllRecord retval = new RefreshAllRecord(); - + retval.setRefreshAll(false); return retval; } - + /** * creates the BookBool record with saveLinkValues set to 0. (don't save link values) * @see org.apache.poi.hssf.record.BookBoolRecord * @see org.apache.poi.hssf.record.Record * @return record containing a BookBoolRecord */ - - protected Record createBookBool() - { + + protected Record createBookBool() { BookBoolRecord retval = new BookBoolRecord(); - + retval.setSaveLinkValues(( short ) 0); return retval; } - + /** * creates a Font record with the following magic values:
* fontheight = 0xc8
@@ -1040,11 +1031,10 @@ public class Workbook
* @see org.apache.poi.hssf.record.Record
* @return record containing a FontRecord
*/
-
- protected Record createFont()
- {
+
+ protected Record createFont() {
FontRecord retval = new FontRecord();
-
+
retval.setFontHeight(( short ) 0xc8);
retval.setAttributes(( short ) 0x0);
retval.setColorPaletteIndex(( short ) 0x7fff);
@@ -1053,7 +1043,7 @@ public class Workbook
retval.setFontName("Arial");
return retval;
}
-
+
/**
* Creates a FormatRecord object
* @param id the number of the format record to create (meaning its position in
@@ -1062,70 +1052,68 @@ public class Workbook
* @see org.apache.poi.hssf.record.FormatRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createFormat(int id)
- { // we'll need multiple editions for
+
+ protected Record createFormat(int id) { // we'll need multiple editions for
FormatRecord retval = new FormatRecord(); // the differnt formats
-
- switch (id)
- {
-
+
+ switch (id) {
+
case 0 :
retval.setIndexCode(( short ) 5);
retval.setFormatStringLength(( byte ) 0x17);
retval.setFormatString("\"$\"#,##0_);\\(\"$\"#,##0\\)");
break;
-
+
case 1 :
retval.setIndexCode(( short ) 6);
retval.setFormatStringLength(( byte ) 0x1c);
retval.setFormatString("\"$\"#,##0_);[Red]\\(\"$\"#,##0\\)");
break;
-
+
case 2 :
retval.setIndexCode(( short ) 7);
retval.setFormatStringLength(( byte ) 0x1d);
retval.setFormatString("\"$\"#,##0.00_);\\(\"$\"#,##0.00\\)");
break;
-
+
case 3 :
retval.setIndexCode(( short ) 8);
retval.setFormatStringLength(( byte ) 0x22);
retval.setFormatString(
- "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)");
+ "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)");
break;
-
+
case 4 :
retval.setIndexCode(( short ) 0x2a);
retval.setFormatStringLength(( byte ) 0x32);
retval.setFormatString(
- "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)");
+ "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)");
break;
-
+
case 5 :
retval.setIndexCode(( short ) 0x29);
retval.setFormatStringLength(( byte ) 0x29);
retval.setFormatString(
- "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)");
+ "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)");
break;
-
+
case 6 :
retval.setIndexCode(( short ) 0x2c);
retval.setFormatStringLength(( byte ) 0x3a);
retval.setFormatString(
- "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)");
+ "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)");
break;
-
+
case 7 :
retval.setIndexCode(( short ) 0x2b);
retval.setFormatStringLength(( byte ) 0x31);
retval.setFormatString(
- "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)");
+ "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)");
break;
}
return retval;
}
-
+
/**
* Creates an ExtendedFormatRecord object
* @param id the number of the extended format record to create (meaning its position in
@@ -1135,14 +1123,12 @@ public class Workbook
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createExtendedFormat(int id)
- { // we'll need multiple editions
+
+ protected Record createExtendedFormat(int id) { // we'll need multiple editions
ExtendedFormatRecord retval = new ExtendedFormatRecord();
-
- switch (id)
- {
-
+
+ switch (id) {
+
case 0 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1154,7 +1140,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 1 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0);
@@ -1166,7 +1152,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 2 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0);
@@ -1178,7 +1164,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 3 :
retval.setFontIndex(( short ) 2);
retval.setFormatIndex(( short ) 0);
@@ -1190,7 +1176,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 4 :
retval.setFontIndex(( short ) 2);
retval.setFormatIndex(( short ) 0);
@@ -1202,7 +1188,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 5 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1214,7 +1200,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 6 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1226,7 +1212,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 7 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1238,7 +1224,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 8 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1250,7 +1236,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 9 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1262,7 +1248,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 10 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1274,7 +1260,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 11 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1286,7 +1272,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 12 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1298,7 +1284,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 13 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1310,7 +1296,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 14 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1322,8 +1308,8 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
- // cell records
+
+ // cell records
case 15 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
@@ -1335,8 +1321,8 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
- // style
+
+ // style
case 16 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2b);
@@ -1348,7 +1334,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 17 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x29);
@@ -1360,7 +1346,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 18 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2c);
@@ -1372,7 +1358,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 19 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2a);
@@ -1384,7 +1370,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 20 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x9);
@@ -1396,8 +1382,8 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
- // unused from this point down
+
+ // unused from this point down
case 21 :
retval.setFontIndex(( short ) 5);
retval.setFormatIndex(( short ) 0x0);
@@ -1409,7 +1395,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 22 :
retval.setFontIndex(( short ) 6);
retval.setFormatIndex(( short ) 0x0);
@@ -1421,7 +1407,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 23 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x31);
@@ -1433,7 +1419,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 24 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x8);
@@ -1445,7 +1431,7 @@ public class Workbook
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
-
+
case 25 :
retval.setFontIndex(( short ) 6);
retval.setFormatIndex(( short ) 0x8);
@@ -1460,16 +1446,15 @@ public class Workbook
}
return retval;
}
-
+
/**
* creates an default cell type ExtendedFormatRecord object.
* @return ExtendedFormatRecord with intial defaults (cell-type)
*/
-
- protected ExtendedFormatRecord createExtendedFormat()
- {
+
+ protected ExtendedFormatRecord createExtendedFormat() {
ExtendedFormatRecord retval = new ExtendedFormatRecord();
-
+
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x0);
retval.setCellOptions(( short ) 0x1);
@@ -1481,7 +1466,7 @@ public class Workbook
retval.setFillPaletteOptions(( short ) 0x20c0);
return retval;
}
-
+
/**
* Creates a StyleRecord object
* @param id the number of the style record to create (meaning its position in
@@ -1490,44 +1475,42 @@ public class Workbook
* @see org.apache.poi.hssf.record.StyleRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createStyle(int id)
- { // we'll need multiple editions
+
+ protected Record createStyle(int id) { // we'll need multiple editions
StyleRecord retval = new StyleRecord();
-
- switch (id)
- {
-
+
+ switch (id) {
+
case 0 :
retval.setIndex(( short ) 0xffff8010);
retval.setBuiltin(( byte ) 3);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
-
+
case 1 :
retval.setIndex(( short ) 0xffff8011);
retval.setBuiltin(( byte ) 6);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
-
+
case 2 :
retval.setIndex(( short ) 0xffff8012);
retval.setBuiltin(( byte ) 4);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
-
+
case 3 :
retval.setIndex(( short ) 0xffff8013);
retval.setBuiltin(( byte ) 7);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
-
+
case 4 :
retval.setIndex(( short ) 0xffff8000);
retval.setBuiltin(( byte ) 0);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
-
+
case 5 :
retval.setIndex(( short ) 0xffff8014);
retval.setBuiltin(( byte ) 5);
@@ -1536,22 +1519,21 @@ public class Workbook
}
return retval;
}
-
+
/**
* Creates the UseSelFS object with the use natural language flag set to 0 (false)
* @return record containing a UseSelFSRecord
* @see org.apache.poi.hssf.record.UseSelFSRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createUseSelFS()
- {
+
+ protected Record createUseSelFS() {
UseSelFSRecord retval = new UseSelFSRecord();
-
+
retval.setFlag(( short ) 0);
return retval;
}
-
+
/**
* create a "bound sheet" or "bundlesheet" (depending who you ask) record
* Always sets the sheet's bof to 0. You'll need to set that yourself.
@@ -1560,14 +1542,12 @@ public class Workbook
* @see org.apache.poi.hssf.record.BoundSheetRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createBoundSheet(int id)
- { // 1,2,3 sheets
+
+ protected Record createBoundSheet(int id) { // 1,2,3 sheets
BoundSheetRecord retval = new BoundSheetRecord();
-
- switch (id)
- {
-
+
+ switch (id) {
+
case 0 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
@@ -1575,7 +1555,7 @@ public class Workbook
retval.setCompressedUnicodeFlag(( byte ) 0);
retval.setSheetname("Sheet1");
break;
-
+
case 1 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
@@ -1583,7 +1563,7 @@ public class Workbook
retval.setCompressedUnicodeFlag(( byte ) 0);
retval.setSheetname("Sheet2");
break;
-
+
case 2 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
@@ -1594,35 +1574,33 @@ public class Workbook
}
return retval;
}
-
+
/**
* Creates the Country record with the default and current country set to 1
* @return record containing a CountryRecord
* @see org.apache.poi.hssf.record.CountryRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createCountry()
- { // what a novel idea, create your own!
+
+ protected Record createCountry() { // what a novel idea, create your own!
CountryRecord retval = new CountryRecord();
-
+
retval.setDefaultCountry(( short ) 1);
retval.setCurrentCountry(( short ) 1);
return retval;
}
-
+
/**
* Creates the SST record with no strings and the unique/num string set to 0
* @return record containing a SSTRecord
* @see org.apache.poi.hssf.record.SSTRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createSST()
- {
+
+ protected Record createSST() {
return new SSTRecord();
}
-
+
/**
* Creates the ExtendedSST record with numstrings per bucket set to 0x8. HSSF
* doesn't yet know what to do with this thing, but we create it with nothing in
@@ -1632,39 +1610,163 @@ public class Workbook
* @see org.apache.poi.hssf.record.ExtSSTRecord
* @see org.apache.poi.hssf.record.Record
*/
-
- protected Record createExtendedSST()
- {
+
+ protected Record createExtendedSST() {
ExtSSTRecord retval = new ExtSSTRecord();
-
+
retval.setNumStringsPerBucket(( short ) 0x8);
return retval;
}
-
+
/**
* creates the EOF record
* @see org.apache.poi.hssf.record.EOFRecord
* @see org.apache.poi.hssf.record.Record
* @return record containing a EOFRecord
*/
-
- protected Record createEOF()
- {
+
+ protected Record createEOF() {
return new EOFRecord();
}
-
+
+ /** fins the sheet name by his extern sheet index
+ * @param num extern sheet index
+ * @return sheet name
+ */
+ public String findSheetNameFromExternSheet(short num){
+ String result;
+
+ short indexToSheet = externSheet.getREFRecordAt(num).getIndexToFirstSupBook();
+ result = getSheetName(indexToSheet);
+
+ return result;
+ }
+
+ /** returns the extern sheet number for specific sheet number ,
+ * if this sheet doesn't exist in extern sheet , add it
+ * @param sheetNumber sheet number
+ * @return index to extern sheet
+ */
+ public short checkExternSheet(int sheetNumber){
+
+ int i = 0;
+ boolean flag = false;
+ short result = 0;
+
+ if (externSheet == null) {
+ externSheet = createExternSheet();
+ }
+
+ //Trying to find reference to this sheet
+ while (i < externSheet.getNumOfREFStructures() && !flag){
+ ExternSheetSubRecord record = externSheet.getREFRecordAt(i);
+
+ if (record.getIndexToFirstSupBook() == sheetNumber &&
+ record.getIndexToLastSupBook() == sheetNumber){
+ flag = true;
+ result = (short) i;
+ }
+
+ ++i;
+ }
+
+ //We Havent found reference to this sheet
+ if (!flag) {
+ result = addSheetIndexToExternSheet((short) sheetNumber);
+ }
+
+ return result;
+ }
+
+ private short addSheetIndexToExternSheet(short sheetNumber){
+ short result;
+
+ ExternSheetSubRecord record = new ExternSheetSubRecord();
+ record.setIndexToFirstSupBook(sheetNumber);
+ record.setIndexToLastSupBook(sheetNumber);
+ externSheet.addREFRecord(record);
+ externSheet.setNumOfREFStructures((short)(externSheet.getNumOfREFStructures() + 1));
+ result = (short)(externSheet.getNumOfREFStructures() - 1);
+
+ return result;
+ }
+
+
+
+ /** gets the total number of names
+ * @return number of names
+ */
+ public int getNumNames(){
+ int result = names.size();
+
+ return result;
+ }
+
+ /** gets the name record
+ * @param index name index
+ * @return name record
+ */
+ public NameRecord getNameRecord(int index){
+ NameRecord result = (NameRecord) names.get(index);
+
+ return result;
+
+ }
+
+ /** creates new name
+ * @return new name record
+ */
+ public NameRecord createName(){
+
+ NameRecord name = new NameRecord();
+
+ records.add(++namepos, name);
+ names.add(name);
+
+ return name;
+ }
+
+ /** removes the name
+ * @param namenum name index
+ */
+ public void removeName(int namenum){
+ if (names.size() > namenum) {
+ records.remove(namepos - (names.size() - 1) + namenum);
+ namepos--;
+ names.remove(namenum);
+ }
+
+ }
+
+ /** creates a new extern sheet record
+ * @return the new extern sheet record
+ */
+ protected ExternSheetRecord createExternSheet(){
+ ExternSheetRecord rec = new ExternSheetRecord();
+
+ records.add(supbookpos + 1 , rec);
+
+ //We also adds the supBook for internal reference
+ SupBookRecord supbook = new SupBookRecord();
+
+ supbook.setNumberOfSheets((short)getNumSheets());
+ supbook.setFlag();
+
+ records.add(supbookpos + 1 , supbook);
+
+ return rec;
+ }
+
+
/**
* Returns the first occurance of a record matching a particular sid.
*/
-
- public Record findFirstRecordBySid(short sid)
- {
- for (Iterator iterator = records.iterator(); iterator.hasNext(); )
- {
+
+ public Record findFirstRecordBySid(short sid) {
+ for (Iterator iterator = records.iterator(); iterator.hasNext(); ) {
Record record = ( Record ) iterator.next();
-
- if (record.getSid() == sid)
- {
+
+ if (record.getSid() == sid) {
return record;
}
}
diff --git a/src/java/org/apache/poi/hssf/record/SupBookRecord.java b/src/java/org/apache/poi/hssf/record/SupBookRecord.java
new file mode 100644
index 0000000000..e0e34d533e
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/SupBookRecord.java
@@ -0,0 +1,176 @@
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Description: A Extrenal Workbook Deciption (Sup Book) + * Its only a dummy record for making new ExternSheet Record
+ * REFERENCE:
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @version 1.0-pre
+ */
+
+public class SupBookRecord extends Record
+{
+ public final static short sid = 0x1AE;
+ private short field_1_number_of_sheets;
+ private short field_2_flag;
+
+
+ public SupBookRecord()
+ {
+ }
+
+ /**
+ * Constructs a Extern Sheet record and sets its fields appropriately.
+ *
+ * @param id id must be 0x16 or an exception will be throw upon validation
+ * @param size the size of the data area of the record
+ * @param data data of the record (should not contain sid/len)
+ */
+
+ public SupBookRecord(short id, short size, byte[] data)
+ {
+ super(id, size, data);
+ }
+
+ /**
+ * Constructs a Extern Sheet record and sets its fields appropriately.
+ *
+ * @param id id must be 0x16 or an exception will be throw upon validation
+ * @param size the size of the data area of the record
+ * @param data data of the record (should not contain sid/len)
+ * @param offset of the record's data
+ */
+
+ public SupBookRecord(short id, short size, byte[] data, int offset)
+ {
+ super(id, size, data, offset);
+ }
+
+ protected void validateSid(short id)
+ {
+ if (id != sid)
+ {
+ throw new RecordFormatException("NOT An ExternSheet RECORD");
+ }
+ }
+
+ /**
+ * called by the constructor, should set class level fields. Should throw
+ * runtime exception for bad/icomplete data.
+ *
+ * @param data raw data
+ * @param size size of data
+ * @param offset of the record's data (provided a big array of the file)
+ */
+ protected void fillFields(byte [] data, short size, int offset)
+ {
+ //For now We use it only for one case
+ //When we need to add an named range when no named ranges was
+ //before it
+
+ }
+
+
+ public String toString()
+ {
+ return "";
+ }
+
+ /**
+ * 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, sid);
+ LittleEndian.putShort(data, 2 + offset, (short) 4);
+ LittleEndian.putShort(data, 4 + offset, field_1_number_of_sheets);
+ LittleEndian.putShort(data, 6 + offset, field_2_flag);
+
+
+ return getRecordSize();
+ }
+
+ public void setNumberOfSheets(short number){
+ field_1_number_of_sheets = number;
+ }
+
+ public void setFlag(){
+ field_2_flag = 0x0401;
+ }
+
+ public int getRecordSize()
+ {
+ return 4 + 4;
+ }
+
+ public short getSid()
+ {
+ return this.sid;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
new file mode 100644
index 0000000000..a52fcd58a9
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
@@ -0,0 +1,247 @@
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Description: Defined a area in Extern Sheet.
+ * REFERENCE:
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @version 1.0-pre
+ */
+
+public class Area3DPtg extends Ptg
+{
+ public final static short sid = 0x3b;
+ private final static int SIZE = 11; // 10 + 1 for Ptg
+ private short field_1_index_extern_sheet;
+ private short field_2_first_row;
+ private short field_3_last_row;
+ private short field_4_first_column;
+ private short field_5_last_column;
+
+ /** Creates new AreaPtg */
+
+ public Area3DPtg()
+ {
+ }
+
+ public Area3DPtg(byte[] data, int offset)
+ {
+ offset++;
+ field_1_index_extern_sheet = LittleEndian.getShort(data, 0 + offset);
+ field_2_first_row = LittleEndian.getShort(data, 2 + offset);
+ field_3_last_row = LittleEndian.getShort(data, 4 + offset);
+ field_4_first_column = LittleEndian.getShort(data, 6 + offset);
+ field_5_last_column = LittleEndian.getShort(data, 8 + offset);
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("AreaPtg\n");
+ buffer.append("Index to Extern Sheet = " + getExternSheetIndex()).append("\n");
+ buffer.append("firstRow = " + getFirstRow()).append("\n");
+ buffer.append("lastRow = " + getLastRow()).append("\n");
+ buffer.append("firstCol = " + getFirstColumn()).append("\n");
+ buffer.append("lastCol = " + getLastColumn()).append("\n");
+ buffer.append("firstColRowRel= "
+ + isFirstColRowRelative()).append("\n");
+ buffer.append("lastColRowRel = "
+ + isLastColRowRelative()).append("\n");
+ buffer.append("firstColRel = " + isFirstColRelative()).append("\n");
+ buffer.append("lastColRel = " + isLastColRelative()).append("\n");
+ return buffer.toString();
+ }
+
+ public void writeBytes(byte [] array, int offset)
+ {
+ array[ 0 + offset ] = sid;
+ LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
+ LittleEndian.putShort(array, 3 + offset , getFirstRow());
+ LittleEndian.putShort(array, 5 + offset , getLastRow());
+ LittleEndian.putShort(array, 7 + offset , getFirstColumnRaw());
+ LittleEndian.putShort(array, 9 + offset , getLastColumnRaw());
+ }
+
+ public int getSize()
+ {
+ return SIZE;
+ }
+
+ public short getExternSheetIndex(){
+ return field_1_index_extern_sheet;
+ }
+
+ public void setExternSheetIndex(short index){
+ field_1_index_extern_sheet = index;
+ }
+
+ public short getFirstRow()
+ {
+ return field_2_first_row;
+ }
+
+ public void setFirstRow(short row)
+ {
+ field_2_first_row = row;
+ }
+
+ public short getLastRow()
+ {
+ return field_3_last_row;
+ }
+
+ public void setLastRow(short row)
+ {
+ field_3_last_row = row;
+ }
+
+ public short getFirstColumn()
+ {
+ return ( short ) (field_4_first_column & 0xFF);
+ }
+
+ public short getFirstColumnRaw()
+ {
+ return field_4_first_column;
+ }
+
+ public boolean isFirstColRowRelative()
+ {
+ return (((getFirstColumnRaw()) & 0x8000) == 0x8000);
+ }
+
+ public boolean isFirstColRelative()
+ {
+ return (((getFirstColumnRaw()) & 0x4000) == 0x4000);
+ }
+
+ public void setFirstColumn(short column)
+ {
+ field_4_first_column &= 0xFF00;
+ field_4_first_column |= column & 0xFF;
+ }
+
+ public void setFirstColumnRaw(short column)
+ {
+ field_4_first_column = column;
+ }
+
+ public short getLastColumn()
+ {
+ return ( short ) (field_5_last_column & 0xFF);
+ }
+
+ public short getLastColumnRaw()
+ {
+ return field_5_last_column;
+ }
+
+ public boolean isLastColRowRelative()
+ {
+ return (((getLastColumnRaw()) & 0x8000) == 1);
+ }
+
+ public boolean isLastColRelative()
+ {
+ return (((getFirstColumnRaw()) & 0x4000) == 1);
+ }
+
+ public void setLastColumn(short column)
+ {
+ field_5_last_column &= 0xFF00;
+ field_5_last_column |= column & 0xFF;
+ }
+
+ public void setLastColumnRaw(short column)
+ {
+ field_5_last_column = column;
+ }
+
+ public String getArea(){
+ RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
+ String result = ra.getAddress();
+
+ return result;
+ }
+
+ public void setArea(String ref){
+ RangeAddress ra = new RangeAddress(ref);
+
+ String from = ra.getFromCell();
+ String to = ra.getToCell();
+
+ setFirstColumn((short) (ra.getXPosition(from) -1));
+ setFirstRow((short) (ra.getYPosition(from) -1));
+ setLastColumn((short) (ra.getXPosition(to) -1));
+ setLastRow((short) (ra.getYPosition(to) -1));
+
+ }
+
+ public String toFormulaString()
+ {
+ String result = getArea();
+
+ return result;
+ }
+
+
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
index 5db1dbfe97..44eef7ce13 100644
--- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
@@ -113,9 +113,7 @@ public abstract class Ptg
{
byte id = data[ offset + 0 ];
Ptg retval = null;
-
- System.out.println("PTG = " + Integer.toHexString(id) + " (" + id
- + ")");
+
switch (id)
{
@@ -175,6 +173,14 @@ public abstract class Ptg
retval = new ExpPtg(data, offset);
break;
+ case Area3DPtg.sid :
+ retval = new Area3DPtg(data, offset);
+ break;
+
+ case Ref3DPtg.sid:
+ retval = new Ref3DPtg(data, offset);
+ break;
+
default :
// retval = new UnknownPtg();
diff --git a/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
new file mode 100644
index 0000000000..885a8bac1c
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
@@ -0,0 +1,177 @@
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Description: Defined a cell in extern sheet.
+ * REFERENCE:
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @version 1.0-pre
+ */
+
+public class Ref3DPtg extends Ptg {
+ public final static short sid = 0x3a;
+ private final static int SIZE = 7; // 6 + 1 for Ptg
+ private short field_1_index_extern_sheet;
+ private short field_2_row;
+ private short field_3_column;
+
+ /** Creates new AreaPtg */
+
+ public Ref3DPtg() {
+ }
+
+ public Ref3DPtg(byte[] data, int offset) {
+ offset++;
+ field_1_index_extern_sheet = LittleEndian.getShort(data, 0 + offset);
+ field_2_row = LittleEndian.getShort(data, 2 + offset);
+ field_3_column = LittleEndian.getShort(data, 4 + offset);
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("Ref3dPrg\n");
+ buffer.append("Index to Extern Sheet = " + getExternSheetIndex()).append("\n");
+ buffer.append("Row = " + getRow()).append("\n");
+ buffer.append("Col = " + getColumn()).append("\n");
+ buffer.append("ColRowRel= "
+ + isColRowRelative()).append("\n");
+ buffer.append("ColRel = " + isColRelative()).append("\n");
+ return buffer.toString();
+ }
+
+ public void writeBytes(byte [] array, int offset) {
+ array[ 0 + offset ] = sid;
+ LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
+ LittleEndian.putShort(array, 3 + offset , getRow());
+ LittleEndian.putShort(array, 5 + offset , getColumnRaw());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public short getExternSheetIndex(){
+ return field_1_index_extern_sheet;
+ }
+
+ public void setExternSheetIndex(short index){
+ field_1_index_extern_sheet = index;
+ }
+
+ public short getRow() {
+ return field_2_row;
+ }
+
+ public void setRow(short row) {
+ field_2_row = row;
+ }
+
+ public short getColumn() {
+ return ( short ) (field_3_column & 0xFF);
+ }
+
+ public short getColumnRaw() {
+ return field_3_column;
+ }
+
+ public boolean isColRowRelative() {
+ return (((getColumnRaw()) & 0x8000) == 0x8000);
+ }
+
+ public boolean isColRelative() {
+ return (((getColumnRaw()) & 0x4000) == 0x4000);
+ }
+
+ public void setColumn(short column) {
+ field_3_column &= 0xFF00;
+ field_3_column |= column & 0xFF;
+ }
+
+ public void setColumnRaw(short column) {
+ field_3_column = column;
+ }
+
+ public String getArea(){
+ RangeAddress ra = new RangeAddress("");
+
+ String result = (ra.numTo26Sys(getColumn()) + (getRow() + 1));
+
+ return result;
+ }
+
+ public void setArea(String ref){
+ RangeAddress ra = new RangeAddress(ref);
+
+ String from = ra.getFromCell();
+
+ setColumn((short) (ra.getXPosition(from) -1));
+ setRow((short) (ra.getYPosition(from) -1));
+
+ }
+
+ public String toFormulaString() {
+ String result = getArea();
+
+ return result;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
new file mode 100644
index 0000000000..c4d3fb2583
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
@@ -0,0 +1,170 @@
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * REFERENCE:
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @version 1.0-pre
+ */
+
+public class HSSFName {
+ private Workbook book;
+ private NameRecord name;
+
+ /** 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 the Workbook */
+
+ protected HSSFName(Workbook book, NameRecord name) {
+ this.book = book;
+ this.name = name;
+ }
+
+ /** private default constructor prevents bogus initializationless construction */
+
+ private HSSFName() {
+ }
+
+ /** Get the sheets name which this named range is referenced to
+ * @return sheet name, which this named range refered to
+ */
+ public String getSheetName() {
+ String result ;
+ short indexToExternSheet = name.getExternSheetNumber();
+
+ result = book.findSheetNameFromExternSheet(indexToExternSheet);
+
+ return result;
+ }
+
+ /** gets the name of the named range
+ * @return named range name
+ */
+ public String getNameName(){
+ String result = name.getNameText();
+
+ return result;
+ }
+
+ /** 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());
+ }
+
+ /** gets the reference of the named range
+ * @return reference of the named range
+ */
+ public String getReference() {
+ String result;
+
+ result = getSheetName() + "." + name.getAreaReference();
+
+ return result;
+ }
+
+ /** sets the sheet name which this named range referenced to
+ * @param sheetName the sheet name of the reference
+ */
+ public void setSheetName(String sheetName){
+ int sheetNumber = book.getSheetIndex(sheetName);
+
+ short externSheetNumber = book.checkExternSheet(sheetNumber);
+ name.setExternSheetNumber(externSheetNumber);
+// name.setIndexToSheet(externSheetNumber);
+ }
+
+ /** sets the reference of this named range
+ * @param ref the reference to set
+ */
+ public void setReference(String ref){
+ RangeAddress ra = new RangeAddress(ref);
+
+ String sheetName = ra.getSheetName();
+
+ if (ra.hasSheetName()) {
+ setSheetName(sheetName);
+ }
+
+ if (ra.getFromCell().equals(ra.getToCell()) == false) {
+ name.setAreaReference(ra.getFromCell() + ":" + ra.getToCell());
+ } else {
+ name.setAreaReference(ra.getFromCell());
+ }
+
+ }
+
+
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index e2daea9eb8..46fad9ae1d 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -110,6 +110,13 @@ public class HSSFWorkbook
*/
private ArrayList sheets;
+
+ /**
+ * this holds the HSSFName objects attached to this workbook
+ */
+
+ private ArrayList names;
+
private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
/**
@@ -121,6 +128,7 @@ public class HSSFWorkbook
{
workbook = Workbook.createWorkbook();
sheets = new ArrayList(INITIAL_CAPACITY);
+ names = new ArrayList(INITIAL_CAPACITY);
}
/**
@@ -136,6 +144,8 @@ public class HSSFWorkbook
throws IOException
{
sheets = new ArrayList(INITIAL_CAPACITY);
+ names = new ArrayList(INITIAL_CAPACITY);
+
InputStream stream = fs.createDocumentInputStream("Workbook");
List records = RecordFactory.createRecords(stream);
@@ -157,6 +167,11 @@ public class HSSFWorkbook
// workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
}
+
+ for (int i = 0 ; i < workbook.getNumNames() ; ++i){
+ HSSFName name = new HSSFName(workbook, workbook.getNameRecord(i));
+ names.add(name);
+ }
}
/**
@@ -216,29 +231,23 @@ public class HSSFWorkbook
return workbook.getSheetName(sheet);
}
- /**
+ /*
* get the sheet's index
* @param name sheet name
* @return sheet index or -1 if it was not found.
*/
+ /** Returns the index of the sheet by his name
+ * @param name the sheet name
+ * @return index of the sheet (0 based)
+ */
public int getSheetIndex(String name)
{
- int retval = -1;
-
- for (int k = 0; k < sheets.size(); k++)
- {
- String sheet = workbook.getSheetName(k);
-
- if (sheet.equals(name))
- {
- retval = k;
- break;
- }
- }
+ int retval = workbook.getSheetIndex(name);
+
return retval;
}
-
+
/**
* create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and returns
* the high level representation. Use this to create new sheets.
@@ -534,4 +543,87 @@ public class HSSFWorkbook
{
return workbook;
}
+
+ /** gets the total number of named ranges in the workboko
+ * @return number of named ranges
+ */
+ public int getNumberOfNames(){
+ int result = names.size();
+ return result;
+ }
+
+ /** gets the Named range
+ * @param index position of the named range
+ * @return named range high level
+ */
+ public HSSFName getNameAt(int index){
+ HSSFName result = (HSSFName) names.get(index);
+
+ return result;
+ }
+
+ /** gets the named range name
+ * @param index the named range index (0 based)
+ * @return named range name
+ */
+ public String getNameName(int index){
+ String result = getNameAt(index).getNameName();
+
+ return result;
+ }
+
+
+ /** creates a new named range and add it to the model
+ * @return named range high level
+ */
+ public HSSFName createName(){
+ NameRecord nameRecord = workbook.createName();
+
+ HSSFName newName = new HSSFName(workbook, nameRecord);
+
+ names.add(newName);
+
+ return newName;
+ }
+
+ /** gets the named range index by his name
+ * @param name named range name
+ * @return named range index
+ */
+ public int getNameIndex(String name)
+ {
+ int retval = -1;
+
+ for (int k = 0; k < names.size(); k++)
+ {
+ String nameName = getNameName(k);
+
+ if (nameName.equals(name))
+ {
+ retval = k;
+ break;
+ }
+ }
+ return retval;
+ }
+
+
+ /** remove the named range by his index
+ * @param index named range index (0 based)
+ */
+ public void removeName(int index){
+ names.remove(index);
+ workbook.removeName(index);
+ }
+
+ /** remove the named range by his name
+ * @param name named range name
+ */
+ public void removeName(String name){
+ int index = getNameIndex(name);
+
+ removeName(index);
+
+ }
+
}
diff --git a/src/java/org/apache/poi/hssf/util/RangeAddress.java b/src/java/org/apache/poi/hssf/util/RangeAddress.java
new file mode 100644
index 0000000000..3e9289e95c
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/util/RangeAddress.java
@@ -0,0 +1,392 @@
+package org.apache.poi.hssf.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Description: provides connectivity utilities for ranges
+ * REFERENCE:
+ * @author IgOr KaTz && EuGeNe BuMaGiN (Tal Moshaiov) (VistaPortal LDT.) + * @version 1.0 + */ + +public class RangeAddress { + final static int WRONG_POS = -1; + final static int MAX_HEIGHT = 66666; + final static char SO_FORMNAME_ENCLOSURE = '\''; + String m_sheetName; + String m_cellFrom; + String m_cellTo; + + public RangeAddress (String _url) { + init (_url); + } + + public RangeAddress (int _startCol, int _startRow, int _endCol, int _endRow) { + init (numTo26Sys (_startCol) + _startRow + ":" + + numTo26Sys (_endCol) + _endRow); + } + + public String getAddress (){ + String result = ""; + if(m_sheetName != null) + result += m_sheetName; + if(m_cellFrom != null){ + result += m_cellFrom; + if(m_cellTo != null) + result += ":" + m_cellTo; + } + return result; + } + + public String getSheetName (){ + return m_sheetName; + } + + public String getRange (){ + String result = ""; + if(m_cellFrom != null){ + result += m_cellFrom; + if(m_cellTo != null) + result += ":" + m_cellTo; + } + return result; + } + + public boolean isCellOk (String _cell){ + if (_cell != null){ + if ( (getYPosition (_cell) != WRONG_POS) && + (getXPosition (_cell) != WRONG_POS) ) + return true; + else + return false; + } else + return false; + } + + public boolean isSheetNameOk (){ + return isSheetNameOk (m_sheetName); + } + + private static boolean intern_isSheetNameOk (String _sheetName, boolean _canBeWaitSpace){ + for (int i = 0 ; i < _sheetName.length (); i++){ + char ch = _sheetName.charAt (i); + if (! (Character.isLetterOrDigit (ch) || (ch == '_')|| + _canBeWaitSpace&&(ch == ' '))){ + return false; + } + } + return true; + } + + public static boolean isSheetNameOk (String _sheetName){ + boolean res = false; + if ( ( _sheetName != null) && !_sheetName.equals ("")){ + res = intern_isSheetNameOk (_sheetName,true); + }else + res = true; + return res; + } + + + public String getFromCell (){ + return m_cellFrom; + } + + public String getToCell (){ + return m_cellTo; + } + + public int getWidth (){ + if(m_cellFrom != null && m_cellTo != null){ + int toX = getXPosition (m_cellTo); + int fromX = getXPosition (m_cellFrom); + if ((toX == WRONG_POS) || (fromX == WRONG_POS)){ + return 0; + }else + return toX - fromX + 1; + } + return 0; + } + + public int getHeight (){ + if(m_cellFrom != null && m_cellTo != null){ + int toY = getYPosition (m_cellTo); + int fromY = getYPosition (m_cellFrom); + if ((toY == WRONG_POS) || (fromY == WRONG_POS)){ + return 0; + }else + return toY - fromY + 1; + } + return 0; + } + + public void setSize (int _width, int _height){ + if(m_cellFrom == null) + m_cellFrom = "a1"; + int tlX, tlY, rbX, rbY; + tlX = getXPosition (m_cellFrom); + tlY = getYPosition (m_cellFrom); + m_cellTo = numTo26Sys (tlX + _width - 1); + m_cellTo += String.valueOf (tlY + _height - 1); + } + + public boolean hasSheetName (){ + if(m_sheetName == null) + return false; + return true; + } + + public boolean hasRange (){ + if(m_cellFrom == null || m_cellTo == null) + return false; + return true; + } + + public boolean hasCell (){ + if(m_cellFrom == null) + return false; + return true; + } + + private void init (String _url){ + + _url = removeString(_url, "$"); + _url = removeString(_url, "'"); + + String[] urls = parseURL (_url); + m_sheetName = urls[0]; + m_cellFrom = urls[1]; + m_cellTo = urls[2]; + + //What if range is one celled ? + if (m_cellTo == null){ + m_cellTo = m_cellFrom; + } + + //Removing noneeds characters + m_cellTo = removeString(m_cellTo,"."); + + + } + + private String[] parseURL (String _url){ + String[] result = new String[3]; + int index = _url.indexOf(':'); + if (index >= 0) { + String fromStr = _url.substring(0, index); + String toStr = _url.substring(index+1); + index = fromStr.indexOf('.'); + if (index >= 0) { + result[0] = fromStr.substring(0, index); + result[1] = fromStr.substring(index+1); + } else { + result[1] = fromStr; + } + index = toStr.indexOf('.'); + if (index >= 0) { + result[2] = toStr.substring(index+1); + } else { + result[2] = toStr; + } + } else { + index = _url.indexOf('.'); + if (index >= 0) { + result[0] = _url.substring(0, index); + result[1] = _url.substring(index+1); + } else { + result[1] = _url; + } + } + return result; + } + + public int getYPosition (String _subrange){ + int result = WRONG_POS; + _subrange = _subrange.trim (); + if (_subrange.length () != 0){ + String digitstr = getDigitPart (_subrange); + try { + result = Integer.parseInt (digitstr); + if (result > MAX_HEIGHT){ + result = WRONG_POS; + } + } + catch (Exception ex) { + + result = WRONG_POS; + } + } + return result; + } + + private static boolean isLetter (String _str){ + boolean res = true; + if ( !_str.equals ("") ){ + for (int i = 0 ; i < _str.length (); i++){ + char ch = _str.charAt (i); + if (! Character.isLetter (ch)){ + res = false; + break; + } + } + }else + res = false; + return res; + } + + public int getXPosition (String _subrange){ + int result = WRONG_POS; + String tmp = filter$ (_subrange); + tmp = this.getCharPart (_subrange); + // we will process only 2 letters ranges + if (isLetter (tmp) && ((tmp.length () == 2)|| (tmp.length () == 1) )){ + result = get26Sys (tmp); + } + return result; + } + + public String getDigitPart (String _value){ + String result = ""; + int digitpos = getFirstDigitPosition (_value); + if(digitpos >= 0){ + result = _value.substring (digitpos); + } + return result; + } + + public String getCharPart (String _value){ + String result = ""; + int digitpos = getFirstDigitPosition (_value); + if(digitpos >= 0){ + result = _value.substring (0, digitpos); + } + return result; + } + + private String filter$ (String _range){ + String res = ""; + for (int i = 0 ; i < _range.length () ; i++){ + char ch = _range.charAt (i); + if ( ch != '$' ){ + res = res + ch; + } + } + return res; + } + + private int getFirstDigitPosition (String _value){ + int result = WRONG_POS; + if(_value != null && _value.trim ().length () == 0){ + return result; + } + _value = _value.trim (); + int length = _value.length (); + for(int i = 0; i < length; i++){ + if(Character.isDigit (_value.charAt (i))){ + result = i; + break; + } + } + return result; + } + + public int get26Sys (String _s){ + int sum = 0; + int multiplier = 1; + if (_s != "") { + for (int i = _s.length ()-1 ; i >= 0 ; i--){ + char ch = _s.charAt (i); + int val = Character.getNumericValue (ch) - Character.getNumericValue ('A')+1; + sum = sum + val * multiplier; + multiplier = multiplier * 26; + } + return sum; + } + return WRONG_POS; + } + + public String numTo26Sys (int _num){ + int sum = 0; + int reminder; + String s =""; + do{ + _num --; + reminder = _num % 26; + int val = 65 + reminder; + _num = _num / 26; + s = (char)val + s; // reverce + }while(_num > 0); + return s; + } + + public String replaceString(String _source , String _oldPattern, + String _newPattern){ + StringBuffer res = new StringBuffer(_source); + int pos = -1; + + while ((pos = res.toString().indexOf(_oldPattern, pos)) > -1){ + res.replace(pos, pos + _oldPattern.length(), _newPattern); + } + + return res.toString(); + } + + public String removeString(String _source, String _match){ + return replaceString(_source, _match, ""); + } + +}