diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index acd7faf71f..c72b8be42d 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -74,7 +74,6 @@ import java.util.ArrayList; * *@author Andrew C. Oliver (acoliver at apache dot org) *@author Glen Stampoultzis (glens at apache.org) - *@created May 10, 2002 *@see #main */ @@ -256,23 +255,27 @@ public class BiffViewer { *@param data Description of the Parameter *@exception IOException Description of the Exception */ - private static void dump(short rectype, short recsize, byte[] data) throws IOException { -// System.out -// .println("fixing to recordize the following"); - System.out.print("rectype = 0x" - + Integer.toHexString(rectype)); - System.out.println(", recsize = 0x" - + Integer.toHexString(recsize)); + private static void dump( short rectype, short recsize, byte[] data ) throws IOException + { + // System.out + // .println("fixing to recordize the following"); + System.out.print( "rectype = 0x" + + Integer.toHexString( rectype ) ); + System.out.println( ", recsize = 0x" + + Integer.toHexString( recsize ) ); System.out.println( - "-BEGIN DUMP---------------------------------"); - if (data.length > 0) { - HexDump.dump(data, 0, System.out, 0); - } else { - System.out.println("**NO RECORD DATA**"); + "-BEGIN DUMP---------------------------------" ); + if ( data.length > 0 ) + { + HexDump.dump( data, 0, System.out, 0 ); } -// System.out.println(); + else + { + System.out.println( "**NO RECORD DATA**" ); + } + // System.out.println(); System.out.println( - "-END DUMP-----------------------------------"); + "-END DUMP-----------------------------------" ); } @@ -286,353 +289,361 @@ public class BiffViewer { *@return Description of the Return Value */ - private static Record[] createRecord(short rectype, short size, - byte[] data) { + private static Record[] createRecord( short rectype, short size, + byte[] data ) + { Record retval = null; Record[] realretval = null; // int irectype = rectype; - switch (rectype) { + switch ( rectype ) + { case ChartRecord.sid: - retval = new ChartRecord(rectype, size, data); + retval = new ChartRecord( rectype, size, data ); break; case ChartFormatRecord.sid: - retval = new ChartFormatRecord(rectype, size, data); + retval = new ChartFormatRecord( rectype, size, data ); break; case SeriesRecord.sid: - retval = new SeriesRecord(rectype, size, data); + retval = new SeriesRecord( rectype, size, data ); break; case BeginRecord.sid: - retval = new BeginRecord(rectype, size, data); + retval = new BeginRecord( rectype, size, data ); break; case EndRecord.sid: - retval = new EndRecord(rectype, size, data); + retval = new EndRecord( rectype, size, data ); break; case BOFRecord.sid: - retval = new BOFRecord(rectype, size, data); + retval = new BOFRecord( rectype, size, data ); break; case InterfaceHdrRecord.sid: - retval = new InterfaceHdrRecord(rectype, size, data); + retval = new InterfaceHdrRecord( rectype, size, data ); break; case MMSRecord.sid: - retval = new MMSRecord(rectype, size, data); + retval = new MMSRecord( rectype, size, data ); break; case InterfaceEndRecord.sid: - retval = new InterfaceEndRecord(rectype, size, data); + retval = new InterfaceEndRecord( rectype, size, data ); break; case WriteAccessRecord.sid: - retval = new WriteAccessRecord(rectype, size, data); + retval = new WriteAccessRecord( rectype, size, data ); break; case CodepageRecord.sid: - retval = new CodepageRecord(rectype, size, data); + retval = new CodepageRecord( rectype, size, data ); break; case DSFRecord.sid: - retval = new DSFRecord(rectype, size, data); + retval = new DSFRecord( rectype, size, data ); break; case TabIdRecord.sid: - retval = new TabIdRecord(rectype, size, data); + retval = new TabIdRecord( rectype, size, data ); break; case FnGroupCountRecord.sid: - retval = new FnGroupCountRecord(rectype, size, data); + retval = new FnGroupCountRecord( rectype, size, data ); break; case WindowProtectRecord.sid: - retval = new WindowProtectRecord(rectype, size, data); + retval = new WindowProtectRecord( rectype, size, data ); break; case ProtectRecord.sid: - retval = new ProtectRecord(rectype, size, data); + retval = new ProtectRecord( rectype, size, data ); break; case PasswordRecord.sid: - retval = new PasswordRecord(rectype, size, data); + retval = new PasswordRecord( rectype, size, data ); break; case ProtectionRev4Record.sid: - retval = new ProtectionRev4Record(rectype, size, data); + retval = new ProtectionRev4Record( rectype, size, data ); break; case PasswordRev4Record.sid: - retval = new PasswordRev4Record(rectype, size, data); + retval = new PasswordRev4Record( rectype, size, data ); break; case WindowOneRecord.sid: - retval = new WindowOneRecord(rectype, size, data); + retval = new WindowOneRecord( rectype, size, data ); break; case BackupRecord.sid: - retval = new BackupRecord(rectype, size, data); + retval = new BackupRecord( rectype, size, data ); break; case HideObjRecord.sid: - retval = new HideObjRecord(rectype, size, data); + retval = new HideObjRecord( rectype, size, data ); break; case DateWindow1904Record.sid: - retval = new DateWindow1904Record(rectype, size, data); + retval = new DateWindow1904Record( rectype, size, data ); break; case PrecisionRecord.sid: - retval = new PrecisionRecord(rectype, size, data); + retval = new PrecisionRecord( rectype, size, data ); break; case RefreshAllRecord.sid: - retval = new RefreshAllRecord(rectype, size, data); + retval = new RefreshAllRecord( rectype, size, data ); break; case BookBoolRecord.sid: - retval = new BookBoolRecord(rectype, size, data); + retval = new BookBoolRecord( rectype, size, data ); break; case FontRecord.sid: - retval = new FontRecord(rectype, size, data); + retval = new FontRecord( rectype, size, data ); break; case FormatRecord.sid: - retval = new FormatRecord(rectype, size, data); + retval = new FormatRecord( rectype, size, data ); break; case ExtendedFormatRecord.sid: - retval = new ExtendedFormatRecord(rectype, size, data); + retval = new ExtendedFormatRecord( rectype, size, data ); break; case StyleRecord.sid: - retval = new StyleRecord(rectype, size, data); + retval = new StyleRecord( rectype, size, data ); break; case UseSelFSRecord.sid: - retval = new UseSelFSRecord(rectype, size, data); + retval = new UseSelFSRecord( rectype, size, data ); break; case BoundSheetRecord.sid: - retval = new BoundSheetRecord(rectype, size, data); + retval = new BoundSheetRecord( rectype, size, data ); break; case CountryRecord.sid: - retval = new CountryRecord(rectype, size, data); + retval = new CountryRecord( rectype, size, data ); break; case SSTRecord.sid: - retval = new SSTRecord(rectype, size, data); + retval = new SSTRecord( rectype, size, data ); break; case ExtSSTRecord.sid: - retval = new ExtSSTRecord(rectype, size, data); + retval = new ExtSSTRecord( rectype, size, data ); break; case EOFRecord.sid: - retval = new EOFRecord(rectype, size, data); + retval = new EOFRecord( rectype, size, data ); break; case IndexRecord.sid: - retval = new IndexRecord(rectype, size, data); + retval = new IndexRecord( rectype, size, data ); break; case CalcModeRecord.sid: - retval = new CalcModeRecord(rectype, size, data); + retval = new CalcModeRecord( rectype, size, data ); break; case CalcCountRecord.sid: - retval = new CalcCountRecord(rectype, size, data); + retval = new CalcCountRecord( rectype, size, data ); break; case RefModeRecord.sid: - retval = new RefModeRecord(rectype, size, data); + retval = new RefModeRecord( rectype, size, data ); break; case IterationRecord.sid: - retval = new IterationRecord(rectype, size, data); + retval = new IterationRecord( rectype, size, data ); break; case DeltaRecord.sid: - retval = new DeltaRecord(rectype, size, data); + retval = new DeltaRecord( rectype, size, data ); break; case SaveRecalcRecord.sid: - retval = new SaveRecalcRecord(rectype, size, data); + retval = new SaveRecalcRecord( rectype, size, data ); break; case PrintHeadersRecord.sid: - retval = new PrintHeadersRecord(rectype, size, data); + retval = new PrintHeadersRecord( rectype, size, data ); break; case PrintGridlinesRecord.sid: - retval = new PrintGridlinesRecord(rectype, size, data); + retval = new PrintGridlinesRecord( rectype, size, data ); break; case GridsetRecord.sid: - retval = new GridsetRecord(rectype, size, data); + retval = new GridsetRecord( rectype, size, data ); break; case GutsRecord.sid: - retval = new GutsRecord(rectype, size, data); + retval = new GutsRecord( rectype, size, data ); break; case DefaultRowHeightRecord.sid: - retval = new DefaultRowHeightRecord(rectype, size, data); + retval = new DefaultRowHeightRecord( rectype, size, data ); break; case WSBoolRecord.sid: - retval = new WSBoolRecord(rectype, size, data); + retval = new WSBoolRecord( rectype, size, data ); break; case HeaderRecord.sid: - retval = new HeaderRecord(rectype, size, data); + retval = new HeaderRecord( rectype, size, data ); break; case FooterRecord.sid: - retval = new FooterRecord(rectype, size, data); + retval = new FooterRecord( rectype, size, data ); break; case HCenterRecord.sid: - retval = new HCenterRecord(rectype, size, data); + retval = new HCenterRecord( rectype, size, data ); break; case VCenterRecord.sid: - retval = new VCenterRecord(rectype, size, data); + retval = new VCenterRecord( rectype, size, data ); break; case PrintSetupRecord.sid: - retval = new PrintSetupRecord(rectype, size, data); + retval = new PrintSetupRecord( rectype, size, data ); break; case DefaultColWidthRecord.sid: - retval = new DefaultColWidthRecord(rectype, size, data); + retval = new DefaultColWidthRecord( rectype, size, data ); break; case DimensionsRecord.sid: - retval = new DimensionsRecord(rectype, size, data); + retval = new DimensionsRecord( rectype, size, data ); break; case RowRecord.sid: - retval = new RowRecord(rectype, size, data); + retval = new RowRecord( rectype, size, data ); break; case LabelSSTRecord.sid: - retval = new LabelSSTRecord(rectype, size, data); + retval = new LabelSSTRecord( rectype, size, data ); break; case RKRecord.sid: - retval = new RKRecord(rectype, size, data); + retval = new RKRecord( rectype, size, data ); break; case NumberRecord.sid: - retval = new NumberRecord(rectype, size, data); + retval = new NumberRecord( rectype, size, data ); break; case DBCellRecord.sid: - retval = new DBCellRecord(rectype, size, data); + retval = new DBCellRecord( rectype, size, data ); break; case WindowTwoRecord.sid: - retval = new WindowTwoRecord(rectype, size, data); + retval = new WindowTwoRecord( rectype, size, data ); break; case SelectionRecord.sid: - retval = new SelectionRecord(rectype, size, data); + retval = new SelectionRecord( rectype, size, data ); break; case ContinueRecord.sid: - retval = new ContinueRecord(rectype, size, data); + retval = new ContinueRecord( rectype, size, data ); break; case LabelRecord.sid: - retval = new LabelRecord(rectype, size, data); + retval = new LabelRecord( rectype, size, data ); break; case MulRKRecord.sid: - retval = new MulRKRecord(rectype, size, data); + retval = new MulRKRecord( rectype, size, data ); break; case MulBlankRecord.sid: - retval = new MulBlankRecord(rectype, size, data); + retval = new MulBlankRecord( rectype, size, data ); break; case BlankRecord.sid: - retval = new BlankRecord(rectype, size, data); + retval = new BlankRecord( rectype, size, data ); break; case BoolErrRecord.sid: - retval = new BoolErrRecord(rectype, size, data); + retval = new BoolErrRecord( rectype, size, data ); break; case ColumnInfoRecord.sid: - retval = new ColumnInfoRecord(rectype, size, data); + retval = new ColumnInfoRecord( rectype, size, data ); break; case MergeCellsRecord.sid: - retval = new MergeCellsRecord(rectype, size, data); + retval = new MergeCellsRecord( rectype, size, data ); break; case AreaRecord.sid: - retval = new AreaRecord(rectype, size, data); + retval = new AreaRecord( rectype, size, data ); break; case DataFormatRecord.sid: - retval = new DataFormatRecord(rectype, size, data); + retval = new DataFormatRecord( rectype, size, data ); break; case BarRecord.sid: - retval = new BarRecord(rectype, size, data); + retval = new BarRecord( rectype, size, data ); break; case DatRecord.sid: - retval = new DatRecord(rectype, size, data); + retval = new DatRecord( rectype, size, data ); break; case PlotGrowthRecord.sid: - retval = new PlotGrowthRecord(rectype, size, data); + retval = new PlotGrowthRecord( rectype, size, data ); break; case UnitsRecord.sid: - retval = new UnitsRecord(rectype, size, data); + retval = new UnitsRecord( rectype, size, data ); break; case FrameRecord.sid: - retval = new FrameRecord(rectype, size, data); + retval = new FrameRecord( rectype, size, data ); break; case ValueRangeRecord.sid: - retval = new ValueRangeRecord(rectype, size, data); + retval = new ValueRangeRecord( rectype, size, data ); break; case SeriesListRecord.sid: - retval = new SeriesListRecord(rectype, size, data); + retval = new SeriesListRecord( rectype, size, data ); break; case FontBasisRecord.sid: - retval = new FontBasisRecord(rectype, size, data); + retval = new FontBasisRecord( rectype, size, data ); break; case FontIndexRecord.sid: - retval = new FontIndexRecord(rectype, size, data); + retval = new FontIndexRecord( rectype, size, data ); break; case LineFormatRecord.sid: - retval = new LineFormatRecord(rectype, size, data); + retval = new LineFormatRecord( rectype, size, data ); break; case AreaFormatRecord.sid: - retval = new AreaFormatRecord(rectype, size, data); + retval = new AreaFormatRecord( rectype, size, data ); break; case LinkedDataRecord.sid: - retval = new LinkedDataRecord(rectype, size, data); + retval = new LinkedDataRecord( rectype, size, data ); break; case FormulaRecord.sid: - retval = new FormulaRecord(rectype, size, data); + retval = new FormulaRecord( rectype, size, data ); break; case SheetPropertiesRecord.sid: - retval = new SheetPropertiesRecord(rectype, size, data); + retval = new SheetPropertiesRecord( rectype, size, data ); break; case DefaultDataLabelTextPropertiesRecord.sid: - retval = new DefaultDataLabelTextPropertiesRecord(rectype, size, data); + retval = new DefaultDataLabelTextPropertiesRecord( rectype, size, data ); break; case TextRecord.sid: - retval = new TextRecord(rectype, size, data); + retval = new TextRecord( rectype, size, data ); break; case AxisParentRecord.sid: - retval = new AxisParentRecord(rectype, size, data); + retval = new AxisParentRecord( rectype, size, data ); break; case AxisLineFormatRecord.sid: - retval = new AxisLineFormatRecord(rectype, size, data); + retval = new AxisLineFormatRecord( rectype, size, data ); break; case SupBookRecord.sid: - retval = new SupBookRecord(rectype, size, data); + retval = new SupBookRecord( rectype, size, data ); break; case ExternSheetRecord.sid: - retval = new ExternSheetRecord(rectype, size, data); + retval = new ExternSheetRecord( rectype, size, data ); break; case SCLRecord.sid: - retval = new SCLRecord(rectype, size, data); + retval = new SCLRecord( rectype, size, data ); break; case SeriesToChartGroupRecord.sid: - retval = new SeriesToChartGroupRecord(rectype, size, data); + retval = new SeriesToChartGroupRecord( rectype, size, data ); break; case AxisUsedRecord.sid: - retval = new AxisUsedRecord(rectype, size, data); + retval = new AxisUsedRecord( rectype, size, data ); break; case AxisRecord.sid: - retval = new AxisRecord(rectype, size, data); + retval = new AxisRecord( rectype, size, data ); break; case CategorySeriesAxisRecord.sid: - retval = new CategorySeriesAxisRecord(rectype, size, data); - break; + retval = new CategorySeriesAxisRecord( rectype, size, data ); + break; case AxisOptionsRecord.sid: - retval = new AxisOptionsRecord(rectype, size, data); + retval = new AxisOptionsRecord( rectype, size, data ); break; case TickRecord.sid: - retval = new TickRecord(rectype, size, data); + retval = new TickRecord( rectype, size, data ); break; case SeriesTextRecord.sid: - retval = new SeriesTextRecord(rectype, size, data); + retval = new SeriesTextRecord( rectype, size, data ); break; case ObjectLinkRecord.sid: - retval = new ObjectLinkRecord(rectype, size, data); + retval = new ObjectLinkRecord( rectype, size, data ); break; case PlotAreaRecord.sid: - retval = new PlotAreaRecord(rectype, size, data); + retval = new PlotAreaRecord( rectype, size, data ); break; case SeriesIndexRecord.sid: - retval = new SeriesIndexRecord(rectype, size, data); + retval = new SeriesIndexRecord( rectype, size, data ); break; case LegendRecord.sid: - retval = new LegendRecord(rectype, size, data); + retval = new LegendRecord( rectype, size, data ); + break; + case LeftMarginRecord.sid: + retval = new LeftMarginRecord( rectype, size, data ); + break; + case LeftMarginRecord.sid: + retval = new LeftMarginRecord( rectype, size, data ); + break; + case RightMarginRecord.sid: + retval = new RightMarginRecord( rectype, size, data ); + break; + case TopMarginRecord.sid: + retval = new TopMarginRecord( rectype, size, data ); + break; + case BottomMarginRecord.sid: + retval = new BottomMarginRecord( rectype, size, data ); + break; + case PaletteRecord.sid: + retval = new PaletteRecord( rectype, size, data ); + break; + case StringRecord.sid: + retval = new StringRecord( rectype, size, data ); break; - case LeftMarginRecord.sid: - retval = new LeftMarginRecord(rectype, size, data); - break; - case RightMarginRecord.sid: - retval = new RightMarginRecord(rectype, size, data); - break; - case TopMarginRecord.sid: - retval = new TopMarginRecord(rectype, size, data); - break; - case BottomMarginRecord.sid: - retval = new BottomMarginRecord(rectype, size, data); - break; - case PaletteRecord.sid: - retval = new PaletteRecord(rectype, size, data); - break; - default: - retval = new UnknownRecord(rectype, size, data); + retval = new UnknownRecord( rectype, size, data ); } - if (realretval == null) { + if ( realretval == null ) + { realretval = new Record[1]; realretval[0] = retval; - System.out.println("recordid = 0x" + Integer.toHexString(rectype) + ", size =" + size); - System.out.println(realretval[0].toString()); + System.out.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size =" + size ); + System.out.println( realretval[0].toString() ); } return realretval; } diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index 22818833d8..ad3a99cc77 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -93,45 +93,45 @@ import org.apache.poi.hssf.util.HSSFColor; public class Workbook { private static final int DEBUG = POILogger.DEBUG; - + // public static Workbook currentBook = null; - + /** * 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 references 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. protected int tabpos = @@ -150,18 +150,18 @@ public class Workbook { 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); - + /** * 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 @@ -174,51 +174,51 @@ public class Workbook { * @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; @@ -238,7 +238,7 @@ public class Workbook { log.log(DEBUG, "found SupBook record at " + k); retval.supbookpos = k; break; - + default : } records.add(rec); @@ -248,22 +248,22 @@ public class Workbook { 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() { 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()); @@ -313,7 +313,7 @@ public class Workbook { 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; @@ -322,18 +322,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() { 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 @@ -342,10 +342,10 @@ 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) { int index = idx; - + if (index > 4) { index -= 1; // adjust for "There is no 4" } @@ -356,10 +356,10 @@ public class Workbook { } 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 @@ -367,10 +367,10 @@ public class Workbook { * * @return FontRecord that was just created */ - + public FontRecord createNewFont() { FontRecord rec = ( FontRecord ) createFont(); - + ++fontpos; ++bspos; ++xfpos; @@ -378,24 +378,24 @@ public class Workbook { 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)); @@ -403,16 +403,16 @@ public class Workbook { (( 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 @@ -421,45 +421,44 @@ public class Workbook { * @param sheetnum the sheet number (0 based) * @param sheetname the name for the sheet */ - + // for compartibility public void setSheetName(int sheetnum, String sheetname ) { setSheetName( sheetnum, sheetname, (byte)0 ); } - + public void setSheetName(int sheetnum, String sheetname, short encoding ) { checkSheets(sheetnum); - BoundSheetRecord sheet = (BoundSheetRecord)boundsheets.get( sheetnum ); sheet.setSheetname(sheetname); sheet.setSheetnameLength( (byte)sheetname.length() ); sheet.setCompressedUnicodeFlag( (byte)encoding ); } - + /** * 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(); } - + /** * 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; @@ -467,12 +466,12 @@ public class Workbook { } 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) { @@ -480,13 +479,13 @@ public class Workbook { } 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); @@ -495,78 +494,78 @@ public class Workbook { 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) @@ -575,7 +574,7 @@ 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) { log.log(DEBUG, "insert to sst string='", string, "' and use16bits= ", new Boolean(use16bits)); @@ -584,7 +583,7 @@ public class Workbook { } 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 @@ -594,56 +593,56 @@ public class Workbook { * * @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()); @@ -654,7 +653,7 @@ public class Workbook { // } 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, @@ -663,14 +662,14 @@ public class Workbook { 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"); @@ -688,7 +687,7 @@ public class Workbook { // 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, @@ -697,120 +696,120 @@ public class Workbook { 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. @@ -818,103 +817,103 @@ public class Workbook { * @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:

* horizontal hold - 0x168

@@ -930,10 +929,10 @@ public class Workbook { * @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); @@ -945,94 +944,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() { 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:

* fontheight = 0xc8

@@ -1046,10 +1045,10 @@ public class Workbook { * @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); @@ -1058,7 +1057,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 @@ -1067,58 +1066,58 @@ 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 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); @@ -1128,7 +1127,7 @@ public class Workbook { } return retval; } - + /** * Creates an ExtendedFormatRecord object * @param id the number of the extended format record to create (meaning its position in @@ -1138,12 +1137,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 ExtendedFormatRecord retval = new ExtendedFormatRecord(); - + switch (id) { - + case 0 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1155,7 +1154,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 1 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0); @@ -1167,7 +1166,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 2 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0); @@ -1179,7 +1178,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 3 : retval.setFontIndex(( short ) 2); retval.setFormatIndex(( short ) 0); @@ -1191,7 +1190,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 4 : retval.setFontIndex(( short ) 2); retval.setFormatIndex(( short ) 0); @@ -1203,7 +1202,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 5 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1215,7 +1214,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 6 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1227,7 +1226,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 7 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1239,7 +1238,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 8 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1251,7 +1250,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 9 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1263,7 +1262,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 10 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1275,7 +1274,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 11 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1287,7 +1286,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 12 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1299,7 +1298,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 13 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1311,7 +1310,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 14 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0); @@ -1323,7 +1322,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + // cell records case 15 : retval.setFontIndex(( short ) 0); @@ -1336,7 +1335,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + // style case 16 : retval.setFontIndex(( short ) 1); @@ -1349,7 +1348,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 17 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0x29); @@ -1361,7 +1360,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 18 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0x2c); @@ -1373,7 +1372,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 19 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0x2a); @@ -1385,7 +1384,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 20 : retval.setFontIndex(( short ) 1); retval.setFormatIndex(( short ) 0x9); @@ -1397,7 +1396,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + // unused from this point down case 21 : retval.setFontIndex(( short ) 5); @@ -1410,7 +1409,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 22 : retval.setFontIndex(( short ) 6); retval.setFormatIndex(( short ) 0x0); @@ -1422,7 +1421,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 23 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0x31); @@ -1434,7 +1433,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 24 : retval.setFontIndex(( short ) 0); retval.setFormatIndex(( short ) 0x8); @@ -1446,7 +1445,7 @@ public class Workbook { retval.setAdtlPaletteOptions(( short ) 0); retval.setFillPaletteOptions(( short ) 0x20c0); break; - + case 25 : retval.setFontIndex(( short ) 6); retval.setFormatIndex(( short ) 0x8); @@ -1461,15 +1460,15 @@ public class Workbook { } 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); @@ -1485,7 +1484,7 @@ public class Workbook { retval.setRightBorderPaletteIdx(HSSFColor.BLACK.index); return retval; } - + /** * Creates a StyleRecord object * @param id the number of the style record to create (meaning its position in @@ -1494,42 +1493,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 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); @@ -1538,21 +1537,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() { 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. @@ -1561,12 +1560,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 BoundSheetRecord retval = new BoundSheetRecord(); - + switch (id) { - + case 0 : retval.setPositionOfBof(0x0); // should be set later retval.setOptionFlags(( short ) 0); @@ -1574,7 +1573,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); @@ -1582,7 +1581,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); @@ -1593,7 +1592,7 @@ public class Workbook { } return retval; } - + /** * Creates the Country record with the default country set to 1 * and current country set to 7 in case of russian locale ("ru_RU") and 1 otherwise @@ -1601,12 +1600,12 @@ public class Workbook { * @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); - + // from Russia with love ;) if ( Locale.getDefault().toString().equals( "ru_RU" ) ) { retval.setCurrentCountry(( short ) 7); @@ -1614,21 +1613,21 @@ public class Workbook { else { 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 @@ -1638,21 +1637,21 @@ public class Workbook { * @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(); } @@ -1668,104 +1667,104 @@ public class Workbook { } return refs; } - + /** 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 */ @@ -1775,37 +1774,37 @@ public class Workbook { 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(); ) { Record record = ( Record ) iterator.next(); - + if (record.getSid() == sid) { return record; } diff --git a/src/java/org/apache/poi/hssf/record/Record.java b/src/java/org/apache/poi/hssf/record/Record.java index 69ec6d728d..867f61f687 100644 --- a/src/java/org/apache/poi/hssf/record/Record.java +++ b/src/java/org/apache/poi/hssf/record/Record.java @@ -182,7 +182,7 @@ public abstract class Record public abstract int serialize(int offset, byte [] data); /** - * gives the current serialized size of the record. + * gives the current serialized size of the record. Should include the sid and reclength (4 bytes). */ public int getRecordSize() diff --git a/src/java/org/apache/poi/hssf/record/RecordFactory.java b/src/java/org/apache/poi/hssf/record/RecordFactory.java index 7e5a6e4d12..29b9422df6 100644 --- a/src/java/org/apache/poi/hssf/record/RecordFactory.java +++ b/src/java/org/apache/poi/hssf/record/RecordFactory.java @@ -78,7 +78,7 @@ public class RecordFactory { private static int NUM_RECORDS = 10000; private static final Class[] records; - + static { if (FormulaRecord.EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) { records = new Class[] @@ -107,9 +107,9 @@ public class RecordFactory LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class, MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class, FormulaRecord.class, BoolErrRecord.class, ExternSheetRecord.class, - NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, - TopMarginRecord.class, BottomMarginRecord.class, - PaletteRecord.class + NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, + TopMarginRecord.class, BottomMarginRecord.class, + PaletteRecord.class, StringRecord.class }; } else { records = new Class[] @@ -138,11 +138,11 @@ public class RecordFactory LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class, MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class, BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class, - LeftMarginRecord.class, RightMarginRecord.class, - TopMarginRecord.class, BottomMarginRecord.class, - PaletteRecord.class + LeftMarginRecord.class, RightMarginRecord.class, + TopMarginRecord.class, BottomMarginRecord.class, + PaletteRecord.class, StringRecord.class }; - + } } private static Map recordsMap = recordsToMap(records); diff --git a/src/java/org/apache/poi/hssf/record/StringRecord.java b/src/java/org/apache/poi/hssf/record/StringRecord.java new file mode 100644 index 0000000000..048675ed8c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/StringRecord.java @@ -0,0 +1,242 @@ +/* ==================================================================== + * 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 + * . + */ + +package org.apache.poi.hssf.record; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.StringUtil; + +/** + * Supports the STRING record structure. + * + * @author Glen Stampoultzis (glens at apache.org) + */ +public class StringRecord + extends Record +{ + public final static short sid = 0x207; + private int field_1_string_length; + private byte field_2_unicode_flag; + private String field_3_string; + + + public StringRecord() + { + } + + /** + * Constructs a String record and sets its fields appropriately. + * + * @param id id must be 0x204 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 StringRecord( short id, short size, byte[] data ) + { + super( id, size, data ); + } + + /** + * Constructs an String record and sets its fields appropriately. + * + * @param id id must be 0x204 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 + */ + public StringRecord( short id, short size, byte[] data, int offset ) + { + super( id, size, data, offset ); + } + + + /** + * Throw a runtime exception in the event of a + * record passed with a differing ID. + * + * @param id alleged id for this record + */ + protected void validateSid( short id ) + { + if (id != this.sid) + { + throw new RecordFormatException("Not a valid StringRecord"); + } + } + + /** + * 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 ) + { + field_1_string_length = LittleEndian.getUShort(data, 0 + offset); + field_2_unicode_flag = data[ 2 + offset ]; + if (isUnCompressedUnicode()) + { + field_3_string = StringUtil.getFromUnicode(data, 3 + offset, field_1_string_length ); + } + else + { + field_3_string = new String(data, 3 + offset, getStringLength()); + } + } + + private int getStringLength() + { + return field_1_string_length; + } + + private int getStringByteLength() + { + return isUnCompressedUnicode() ? field_1_string_length * 2 : field_1_string_length; + } + + /** + * gives the current serialized size of the record. Should include the sid and reclength (4 bytes). + */ + public int getRecordSize() + { + return 4 + 2 + 1 + getStringByteLength(); + } + + + /** + * is this uncompressed unicode (16bit)? Or just 8-bit compressed? + * @return isUnicode - True for 16bit- false for 8bit + */ + public boolean isUnCompressedUnicode() + { + return (field_2_unicode_flag == 1); + } + + /** + * 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 ) (2 + getStringByteLength())); + LittleEndian.putUShort(data, 4 + offset, field_1_string_length); + data[6 + offset] = field_2_unicode_flag; + if (isUnCompressedUnicode()) + { + StringUtil.putUncompressedUnicode(field_3_string, data, 7 + offset); + } + else + { + StringUtil.putCompressedUnicode(field_3_string, data, 7 + offset); + } + return getRecordSize(); + } + + /** + * return the non static version of the id for this record. + */ + public short getSid() + { + return sid; + } + + /** + * @return The string represented by this record. + */ + public String getString() + { + return field_3_string; + } + + /** + * Sets whether the string is compressed or not + * @param unicode_flag 1 = uncompressed, 0 = compressed + */ + public void setCompressedFlag( byte unicode_flag ) + { + this.field_2_unicode_flag = unicode_flag; + } + + /** + * Sets the string represented by this record. + */ + public void setString( String string ) + { + this.field_1_string_length = string.length(); + this.field_3_string = string; + } + + + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + + buffer.append("[STRING]\n"); + buffer.append(" .string = ") + .append(field_3_string).append("\n"); + buffer.append("[/STRING]\n"); + return buffer.toString(); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/TestStringRecord.java b/src/testcases/org/apache/poi/hssf/record/TestStringRecord.java new file mode 100644 index 0000000000..7bc2a6524a --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestStringRecord.java @@ -0,0 +1,106 @@ + +/* ==================================================================== + * 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 + * . + */ + + +package org.apache.poi.hssf.record; + + +import junit.framework.TestCase; + +/** + * Tests the serialization and deserialization of the StringRecord + * class works correctly. Test data taken directly from a real + * Excel file. + * + * @author Glen Stampoultzis (glens at apache.org) + */ +public class TestStringRecord + extends TestCase +{ + byte[] data = new byte[] { + (byte)0x0B,(byte)0x00, // length + (byte)0x00, // option + // string + (byte)0x46,(byte)0x61,(byte)0x68,(byte)0x72,(byte)0x7A,(byte)0x65,(byte)0x75,(byte)0x67,(byte)0x74,(byte)0x79,(byte)0x70 + }; + + public TestStringRecord(String name) + { + super(name); + } + + public void testLoad() + throws Exception + { + + StringRecord record = new StringRecord((short)0x207, (short)data.length, data); + assertEquals( "Fahrzeugtyp", record.getString()); + + assertEquals( 18, record.getRecordSize() ); + + record.validateSid((short)0x207); + } + + public void testStore() + { + StringRecord record = new StringRecord(); + record.setString("Fahrzeugtyp"); + + byte [] recordBytes = record.serialize(); + assertEquals(recordBytes.length - 4, data.length); + for (int i = 0; i < data.length; i++) + assertEquals("At offset " + i, data[i], recordBytes[i+4]); + } +}