poi/src/java/org/apache/poi/hssf/model/Workbook.java

1659 lines
56 KiB
Java

/* ====================================================================
* 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
* <http://www.apache.org/>.
*/
package org.apache.poi.hssf.model;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import org.apache.poi.hssf.record.*;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
/**
* Workbook
* Low level model implementation of a Workbook. Provides creational methods
* for settings and objects contained in the workbook object.
* <P>
* This file contains the low level binary records starting at the workbook's BOF and
* ending with the workbook's EOF. Use HSSFWorkbook for a high level representation.
* <P>
* The structures of the highlevel API use references to this to perform most of their
* operations. Its probably unwise to use these low level structures directly unless you
* really know what you're doing. I recommend you read the Microsoft Excel 97 Developer's
* Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
* before even attempting to use this.
*
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook
* @version 1.0-pre
*/
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 "boundsheet" records (aka bundlesheet) so that they can have their
* reference to their "BOF" marker
*/
protected ArrayList boundsheets = new ArrayList();
protected int bspos =
0; // holds the position of the last bound sheet.
protected int tabpos =
0; // holds the position of the tabid record
protected int fontpos =
0; // hold the position of the last font record
protected int numfonts =
0; // hold the number of font records
protected int xfpos =
0; // hold the position of the last extended font record
protected int numxfs =
0; // hold the number of extended format records
private int backuppos =
0; // holds the position of the backup record.
private static POILogger log =
POILogFactory.getLogger(Workbook.class);
/**
* Creates new Workbook with no intitialization --useless right now
* @see #createWorkbook(List)
*/
public Workbook()
{
}
/**
* read support for low level
* API. Pass in an array of Record objects, A Workbook
* object is constructed and passed back with all of its initialization set
* to the passed in records and references to those records held. Unlike Sheet
* workbook does not use an offset (its assumed to be 0) since its first in a file.
* If you need an offset then construct a new array with a 0 offset or write your
* own ;-p.
*
* @param recs an array of Record objects
* @return Workbook object
*/
public static Workbook createWorkbook(List recs)
{
log.log(DEBUG, "Workbook (readfile) created with reclen=",
new Integer(recs.size()));
Workbook retval = new Workbook();
ArrayList records = new ArrayList(recs.size() / 3);
for (int k = 0; k < recs.size(); k++)
{
Record rec = ( Record ) recs.get(k);
if (rec.getSid() == EOFRecord.sid)
{
records.add(rec);
log.log(DEBUG, "found workbook eof record at " + k);
break;
}
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;
default :
}
records.add(rec);
}
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()
{
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());
records.add(retval.createInterfaceEnd());
records.add(retval.createWriteAccess());
records.add(retval.createCodepage());
records.add(retval.createDSF());
records.add(retval.createTabId());
retval.tabpos = records.size() - 1;
records.add(retval.createFnGroupCount());
records.add(retval.createWindowProtect());
records.add(retval.createProtect());
records.add(retval.createPassword());
records.add(retval.createProtectionRev4());
records.add(retval.createPasswordRev4());
records.add(retval.createWindowOne());
records.add(retval.createBackup());
retval.backuppos = records.size() - 1;
records.add(retval.createHideObj());
records.add(retval.createDateWindow1904());
records.add(retval.createPrecision());
records.add(retval.createRefreshAll());
records.add(retval.createBookBool());
records.add(retval.createFont());
records.add(retval.createFont());
records.add(retval.createFont());
records.add(retval.createFont());
retval.fontpos = records.size() - 1; // last font record postion
retval.numfonts = 4;
records.add(retval.createFormat(0));
records.add(retval.createFormat(1));
records.add(retval.createFormat(2));
records.add(retval.createFormat(3));
records.add(retval.createFormat(4));
records.add(retval.createFormat(5));
records.add(retval.createFormat(6));
records.add(retval.createFormat(7));
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++)
{
records.add(retval.createStyle(k));
}
records.add(retval.createUseSelFS());
for (int k = 0; k < 1; k++)
{ // now just do 1
BoundSheetRecord bsr =
( BoundSheetRecord ) retval.createBoundSheet(k);
records.add(bsr);
retval.boundsheets.add(bsr);
retval.bspos = records.size() - 1;
}
records.add(retval.createCountry());
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()
{
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
* many times)
*
* @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)
{
int index = idx;
if (index > 4)
{
index -= 1; // adjust for "There is no 4"
}
if (index > (numfonts - 1))
{
throw new ArrayIndexOutOfBoundsException(
"There are only " + numfonts
+ " font records, you asked for " + idx);
}
FontRecord retval =
( 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
* those pointers as well)
*
* @return FontRecord that was just created
*/
public FontRecord createNewFont()
{
FontRecord rec = ( FontRecord ) createFont();
++fontpos;
++bspos;
++xfpos;
records.add(fontpos, rec);
numfonts++;
return rec;
}
/**
* gets the number of font records
*
* @return number of font records in the "font table"
*/
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)
{
log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetnum),
" at pos=", new Integer(pos));
checkSheets(sheetnum);
(( BoundSheetRecord ) boundsheets.get(sheetnum))
.setPositionOfBof(pos);
}
/**
* Returns the position of the backup record.
*/
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
* we have, except
*
* @param sheetnum the sheet number (0 based)
* @param sheetname the name for the sheet
*/
public void setSheetName(int sheetnum, String sheetname)
{
checkSheets(sheetnum);
(( BoundSheetRecord ) boundsheets.get(sheetnum))
.setSheetname(sheetname);
(( BoundSheetRecord ) boundsheets.get(sheetnum))
.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)
{
return (( BoundSheetRecord ) boundsheets.get(sheetnum))
.getSheetname();
}
/**
* 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)
{
throw new RuntimeException("Sheet number out of bounds!");
}
BoundSheetRecord bsr =
( BoundSheetRecord ) createBoundSheet(sheetnum);
records.add(++bspos, bsr);
boundsheets.add(bsr);
fixTabIdRecord();
}
}
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()
{
TabIdRecord tir = ( TabIdRecord ) records.get(tabpos);
short[] tia = new short[ boundsheets.size() ];
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()
{
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()
{
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)
{
int xfptr = xfpos - (numxfs - 1);
xfptr += index;
ExtendedFormatRecord retval =
( 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()
{
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)
*
* @param string the string to be added to the SSTRecord
* @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)
{
log.log(DEBUG, "insert to sst string='", string, "' and use16bits= ",
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
* (meaning 8bit)
*
* @param string the string to be added to the SSTRecord
*
* @return index of the string within the SSTRecord
*/
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)
{
insertSST();
}
String retval = sst.getString(str);
log.log(DEBUG, "Returning SST for index=", new Integer(str),
" 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()
{
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()
{
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++)
{
// byte[] rec = (( byte [] ) bytes.get(k));
// System.arraycopy(rec, 0, retval, pos, rec.length);
pos += (( Record ) records.get(k)).serialize(pos,
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)
{
log.log(DEBUG, "Serializing Workbook with offsets");
int pos = 0;
for (int k = 0; k < records.size(); k++)
{
pos += (( Record ) records.get(k)).serialize(pos + offset, data); // rec.length;
}
log.log(DEBUG, "Exiting serialize workbook");
return pos;
}
public int getSize()
{
int retval = 0;
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()
{
BOFRecord retval = new BOFRecord();
retval.setVersion(( short ) 0x600);
retval.setType(( short ) 5);
retval.setBuild(( short ) 0x10d3);
// 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()
{
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()
{
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()
{
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()
{
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()
{
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()
{
DSFRecord retval = new DSFRecord();
retval.setDsf(
( 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.
* @see org.apache.poi.hssf.record.TabIdRecord
* @see org.apache.poi.hssf.record.Record
* @return record containing a TabIdRecord
*/
protected Record createTabId()
{
TabIdRecord retval = new TabIdRecord();
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()
{
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()
{
WindowProtectRecord retval = new WindowProtectRecord();
retval.setProtect(
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()
{
ProtectRecord retval = new ProtectRecord();
retval.setProtect(
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()
{
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()
{
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()
{
PasswordRev4Record retval = new PasswordRev4Record();
retval.setPassword(( short ) 0); // no password by default!
return retval;
}
/**
* creates the WindowOne record with the following magic values: <P>
* horizontal hold - 0x168 <P>
* vertical hold - 0x10e <P>
* width - 0x3a5c <P>
* height - 0x23be <P>
* options - 0x38 <P>
* selected tab - 0 <P>
* displayed tab - 0 <P>
* num selected tab- 0 <P>
* tab width ratio - 0x258 <P>
* @see org.apache.poi.hssf.record.WindowOneRecord
* @see org.apache.poi.hssf.record.Record
* @return record containing a WindowOneRecord
*/
protected Record createWindowOne()
{
WindowOneRecord retval = new WindowOneRecord();
retval.setHorizontalHold(( short ) 0x168);
retval.setVerticalHold(( short ) 0x10e);
retval.setWidth(( short ) 0x3a5c);
retval.setHeight(( short ) 0x23be);
retval.setOptions(( short ) 0x38);
retval.setSelectedTab(( short ) 0x0);
retval.setDisplayedTab(( short ) 0x0);
retval.setNumSelectedTabs(( short ) 1);
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()
{
BackupRecord retval = new BackupRecord();
retval.setBackup(
( 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()
{
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()
{
DateWindow1904Record retval = new DateWindow1904Record();
retval.setWindowing(
( 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()
{
PrecisionRecord retval = new PrecisionRecord();
retval.setFullPrecision(
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()
{
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()
{
BookBoolRecord retval = new BookBoolRecord();
retval.setSaveLinkValues(( short ) 0);
return retval;
}
/**
* creates a Font record with the following magic values: <P>
* fontheight = 0xc8<P>
* attributes = 0x0<P>
* color palette index = 0x7fff<P>
* bold weight = 0x190<P>
* Font Name Length = 5 <P>
* Font Name = Arial <P>
*
* @see org.apache.poi.hssf.record.FontRecord
* @see org.apache.poi.hssf.record.Record
* @return record containing a FontRecord
*/
protected Record createFont()
{
FontRecord retval = new FontRecord();
retval.setFontHeight(( short ) 0xc8);
retval.setAttributes(( short ) 0x0);
retval.setColorPaletteIndex(( short ) 0x7fff);
retval.setBoldWeight(( short ) 0x190);
retval.setFontNameLength(( byte ) 5);
retval.setFontName("Arial");
return retval;
}
/**
* Creates a FormatRecord object
* @param id the number of the format record to create (meaning its position in
* a file as M$ Excel would create it.)
* @return record containing a FormatRecord
* @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
FormatRecord retval = new FormatRecord(); // the differnt formats
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\\)");
break;
case 4 :
retval.setIndexCode(( short ) 0x2a);
retval.setFormatStringLength(( byte ) 0x32);
retval.setFormatString(
"_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)");
break;
case 5 :
retval.setIndexCode(( short ) 0x29);
retval.setFormatStringLength(( byte ) 0x29);
retval.setFormatString(
"_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)");
break;
case 6 :
retval.setIndexCode(( short ) 0x2c);
retval.setFormatStringLength(( byte ) 0x3a);
retval.setFormatString(
"_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)");
break;
case 7 :
retval.setIndexCode(( short ) 0x2b);
retval.setFormatStringLength(( byte ) 0x31);
retval.setFormatString(
"_(* #,##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
* a file as MS Excel would create it.)
*
* @return record containing an ExtendedFormatRecord
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @see org.apache.poi.hssf.record.Record
*/
protected Record createExtendedFormat(int id)
{ // we'll need multiple editions
ExtendedFormatRecord retval = new ExtendedFormatRecord();
switch (id)
{
case 0 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 1 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 2 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 3 :
retval.setFontIndex(( short ) 2);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 4 :
retval.setFontIndex(( short ) 2);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 5 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 6 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 7 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 8 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 9 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 10 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 11 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 12 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 13 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 14 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff400);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
// cell records
case 15 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x0);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
// style
case 16 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2b);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 17 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x29);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 18 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2c);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 19 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x2a);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 20 :
retval.setFontIndex(( short ) 1);
retval.setFormatIndex(( short ) 0x9);
retval.setCellOptions(( short ) 0xfffffff5);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0xfffff800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
// unused from this point down
case 21 :
retval.setFontIndex(( short ) 5);
retval.setFormatIndex(( short ) 0x0);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x800);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 22 :
retval.setFontIndex(( short ) 6);
retval.setFormatIndex(( short ) 0x0);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x5c00);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 23 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x31);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x5c00);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 24 :
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x8);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x5c00);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
case 25 :
retval.setFontIndex(( short ) 6);
retval.setFormatIndex(( short ) 0x8);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0x5c00);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
break;
}
return retval;
}
/**
* creates an default cell type ExtendedFormatRecord object.
* @return ExtendedFormatRecord with intial defaults (cell-type)
*/
protected ExtendedFormatRecord createExtendedFormat()
{
ExtendedFormatRecord retval = new ExtendedFormatRecord();
retval.setFontIndex(( short ) 0);
retval.setFormatIndex(( short ) 0x0);
retval.setCellOptions(( short ) 0x1);
retval.setAlignmentOptions(( short ) 0x20);
retval.setIndentionOptions(( short ) 0);
retval.setBorderOptions(( short ) 0);
retval.setPaletteOptions(( short ) 0);
retval.setAdtlPaletteOptions(( short ) 0);
retval.setFillPaletteOptions(( short ) 0x20c0);
return retval;
}
/**
* Creates a StyleRecord object
* @param id the number of the style record to create (meaning its position in
* a file as MS Excel would create it.
* @return record containing a StyleRecord
* @see org.apache.poi.hssf.record.StyleRecord
* @see org.apache.poi.hssf.record.Record
*/
protected Record createStyle(int id)
{ // we'll need multiple editions
StyleRecord retval = new StyleRecord();
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);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
}
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()
{
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.
* @param id either sheet 0,1 or 2.
* @return record containing a BoundSheetRecord
* @see org.apache.poi.hssf.record.BoundSheetRecord
* @see org.apache.poi.hssf.record.Record
*/
protected Record createBoundSheet(int id)
{ // 1,2,3 sheets
BoundSheetRecord retval = new BoundSheetRecord();
switch (id)
{
case 0 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
retval.setSheetnameLength(( byte ) 0x6);
retval.setCompressedUnicodeFlag(( byte ) 0);
retval.setSheetname("Sheet1");
break;
case 1 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
retval.setSheetnameLength(( byte ) 0x6);
retval.setCompressedUnicodeFlag(( byte ) 0);
retval.setSheetname("Sheet2");
break;
case 2 :
retval.setPositionOfBof(0x0); // should be set later
retval.setOptionFlags(( short ) 0);
retval.setSheetnameLength(( byte ) 0x6);
retval.setCompressedUnicodeFlag(( byte ) 0);
retval.setSheetname("Sheet3");
break;
}
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!
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()
{
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
* it hardly just to make Excel happy and our sheets look like Excel's
*
* @return record containing an ExtSSTRecord
* @see org.apache.poi.hssf.record.ExtSSTRecord
* @see org.apache.poi.hssf.record.Record
*/
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()
{
return new EOFRecord();
}
/**
* Returns the first occurance of a record matching a particular sid.
*/
public Record findFirstRecordBySid(short sid)
{
for (Iterator iterator = records.iterator(); iterator.hasNext(); )
{
Record record = ( Record ) iterator.next();
if (record.getSid() == sid)
{
return record;
}
}
return null;
}
}