/** * Gets the specified sheet within this workbook * * @param index the zero based index of the required sheet * @return The sheet specified by the index */ public override Sheet getSheet(int index) { // First see if the last sheet index is the same as this sheet index. // If so, then the same sheet is being re-requested, so simply // return it instead of rereading it if ((lastSheet != null) && lastSheetIndex == index) { return(lastSheet); } // Flush out all of the cached data in the last sheet if (lastSheet != null) { lastSheet.clear(); //if (!settings.getGCDisabled()) // { // System.gc(); // } } lastSheet = (SheetImpl)sheets[index]; lastSheetIndex = index; lastSheet.readSheet(); return(lastSheet); }
/** * Constructs this object * * @param t the raw data * @param fr the formatting records * @param si the sheet */ public ErrorRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); errorCode = data[6]; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param ws the workbook settings * @param dummy dummy overload to indicate a biff 7 workbook */ public LabelRecord(Record t, FormattingRecords fr, SheetImpl si, WorkbookSettings ws, Biff7 dummy) : base(t, fr, si) { byte[] data = getRecord().getData(); length = IntegerHelper.getInt(data[6], data[7]); description = StringHelper.getString(data, length, 8, ws); }
/** * Constructor. Retrieves the index from the raw data and looks it up * in the shared string table * * @param stringTable the shared string table * @param t the raw data * @param fr the formatting records * @param si the sheet */ public LabelSSTRecord(Record t, SSTRecord stringTable, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); index = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); description = stringTable.getString(index); }
/** * Constructs this object from the raw data * * @param num the numerical representation of this * @param xfi the java equivalent of the excel date format * @param fr the formatting records * @param nf flag indicating whether we are using the 1904 date system * @param si the sheet */ public DateRecord(NumberCell num, int xfi, FormattingRecords fr, bool nf, SheetImpl si) { row = num.getRow(); column = num.getColumn(); xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; format = formattingRecords.getDateFormat(xfIndex); // This value represents the number of days since 01 Jan 1900 double numValue = num.getValue(); if (Math.Abs(numValue) < 1) { if (format == null) { format = timeFormat; } time = true; } else { if (format == null) { format = dateFormat; } time = false; } // Work round a bug in excel. Excel seems to think there is a date // called the 29th Feb, 1900 - but in actual fact this was not a leap year. // Therefore for values less than 61 in the 1900 date system, // add one to the numeric value if (!nf && !time && numValue < nonLeapDay) { numValue += 1; } // Get rid of any timezone adjustments - we are not interested // in automatic adjustments // TODO: CML -- don't know what to do here.... // format.setTimeZone(gmtZone); // Convert this to the number of days since 01 Jan 1970 int offsetDays = nf ? utcOffsetDays1904 : utcOffsetDays; double utcDays = numValue - offsetDays; // Convert this into utc by multiplying by the number of milliseconds // in a day. Use the round function prior to ms conversion due // to a rounding feature of Excel (contributed by Jurgen) long utcValue = (long)Math.Round(utcDays * secondsInADay) * msInASecond; date = new System.DateTime(ticksTo1970 + (utcValue * msTicks)); }
/** * Constructs this object from the raw data * * @param t the basic number formula record * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param nf flag indicating whether the 1904 date system is in use * @param si the sheet */ public DateFormulaRecord(NumberFormulaRecord t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, bool nf, SheetImpl si) : base(t, t.getXFIndex(), fr, nf, si) { externalSheet = es; nameTable = nt; data = t.getFormulaData(); }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedBooleanFormulaRecord(Record t, File excelFile, bool v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { value = v; }
/** * Constructs this object from the raw cell data * * @param t the raw cell data * @param fr the formatting records * @param si the sheet containing this cell */ protected CellValue(Record t, FormattingRecords fr, SheetImpl si) : base(t) { byte[] data = getRecord().getData(); row = IntegerHelper.getInt(data[0], data[1]); column = IntegerHelper.getInt(data[2], data[3]); xfIndex = IntegerHelper.getInt(data[4], data[5]); sheet = si; formattingRecords = fr; initialized = false; }
/** * Constructs this string formula * * @param t the record * @param excelFile the excel file * @param fr the formatting record * @param es the external sheet * @param nt the workbook * @param si the sheet * @param dummy the overload indicator */ public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, EmptyString dummy) : base(t, fr, es, nt, si, excelFile.getPos()) { value = string.Empty; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the errorCode * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedErrorFormulaRecord(Record t, File excelFile, int ec, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { errorCode = ec; }
/** * Constructs this cell * * @param r the zero based row * @param c the zero base column * @param xfi the xf index * @param fr the formatting records * @param si the sheet */ public MulBlankCell(int r, int c, int xfi, FormattingRecords fr, SheetImpl si) { row = r; column = c; xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; }
/** * Constructs this number * * @param t the record * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet * @param pos the position of the next record in the file */ public BaseSharedFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, int pos) : base(t, fr, si) { externalSheet = es; nameTable = nt; filePos = pos; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public ErrorFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); Assert.verify(data[6] == 2); errorCode = data[8]; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedNumberFormulaRecord(Record t, File excelFile, double v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { value = v; format = defaultFormat; // format is set up later from the // SharedFormulaRecord }
/** * Constructs this object from the raw data. Used when reading in formula * strings which evaluate to null (in the case of some IF statements) * * @param t the raw data * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); value = string.Empty; }
/** * Constructs this number * * @param r the zero based row * @param c the zero base column * @param val the value * @param xfi the xf index * @param fr the formatting records * @param si the sheet */ public NumberValue(int r, int c, double val, int xfi, FormattingRecords fr, SheetImpl si) { row = r; column = c; value = val; format = defaultFormat; xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the available formats * @param si the sheet */ public NumberRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); value = DoubleHelper.getIEEEDouble(data, 6); // Now get the number format format = fr.getNumberFormat(getXFIndex()); if (format == null) { format = defaultFormat; } }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet */ public BooleanRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { error = false; value = false; byte[] data = getRecord().getData(); error = (data[7] == 1); if (!error) { value = data[6] == 1 ? true : false; } }
/** * Constructs this number formula * * @param nfr the number formula records * @param fr the formatting records * @param nf flag indicating whether this uses the 1904 date system * @param si the sheet * @param pos the position */ public SharedDateFormulaRecord(SharedNumberFormulaRecord nfr, FormattingRecords fr, bool nf, SheetImpl si, int pos) : base(nfr.getRecord(), fr, nfr.getExternalSheet(), nfr.getNameTable(), si, pos) { dateRecord = new DateRecord(nfr, nfr.getXFIndex(), fr, nf, si); value = nfr.getValue(); }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param es the sheet * @param nt the name table */ public BooleanFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; value = false; data = getRecord().getData(); Assert.verify(data[6] != 2); value = data[8] == 1 ? true : false; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param ws the workbook settings */ public LabelRecord(Record t, FormattingRecords fr, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { byte[] data = getRecord().getData(); length = IntegerHelper.getInt(data[6], data[7]); if (data[8] == 0x0) { description = StringHelper.getString(data, length, 9, ws); } else { description = StringHelper.getUnicodeString(data, length, 9); } }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the available cell formats * @param si the sheet */ public RKRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); int rknum = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); value = RKHelper.getDouble(rknum); // Now get the number format format = fr.getNumberFormat(getXFIndex()); if (format == null) { format = defaultFormat; } }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting record * @param es the external sheet * @param nt the name table * @param si the sheet */ public NumberFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); format = fr.getNumberFormat(getXFIndex()); if (format == null) { format = defaultFormat; } value = DoubleHelper.getIEEEDouble(data, 6); }
/** * Constructs this object from the raw data. We need to use the excelFile * to retrieve the string record which follows this formula record * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); int pos = excelFile.getPos(); // Look for the string record in one of the records after the // formula. Put a cap on it to prevent looping Record nextRecord = excelFile.next(); int count = 0; while (nextRecord.getType() != Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4, " @ " + pos); byte[] stringData = nextRecord.getData(); // Read in any continuation records nextRecord = excelFile.peek(); while (nextRecord.getType() == Type.CONTINUE) { nextRecord = excelFile.next(); // move the pointer within the data byte[] d = new byte[stringData.Length + nextRecord.getLength() - 1]; System.Array.Copy(stringData, 0, d, 0, stringData.Length); System.Array.Copy(nextRecord.getData(), 1, d, stringData.Length, nextRecord.getLength() - 1); stringData = d; nextRecord = excelFile.peek(); } readString(stringData, ws); }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param fr the base shared formula * @param es the workbook, which contains the external sheet references * @param nt the workbook * @param si the sheet */ public SharedFormulaRecord(Record t, BaseSharedFormulaRecord fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) { sheet = si; byte[] data = t.getData(); firstRow = IntegerHelper.getInt(data[0], data[1]); lastRow = IntegerHelper.getInt(data[2], data[3]); firstCol = data[4] & 0xff; lastCol = data[5] & 0xff; formulas = new ArrayList(); templateFormula = fr; tokens = new byte[data.Length - 10]; System.Array.Copy(data, 10, tokens, 0, tokens.Length); }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the workbook, which contains the external sheet references * @param nt the name table * @param i a dummy override to indicate that we don't want to do * any shared formula processing * @param si the sheet impl * @param ws the workbook settings */ public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, IgnoreSharedFormula i, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { byte[] data = getRecord().getData(); shared = false; // microsoft and their magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // we have a string formula = new StringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { // We have a bool formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t, fr, es, nt, si); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error formula = new ErrorFormulaRecord(t, fr, es, nt, si); } else { // it is most assuredly a number formula = new NumberFormulaRecord(t, fr, es, nt, si); } }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the workbook, which contains the external sheet references * @param nt the name table * @param si the sheet * @param ws the workbook settings */ public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { byte[] data = getRecord().getData(); shared = false; // Check to see if this forms part of a shared formula int grbit = IntegerHelper.getInt(data[14], data[15]); if ((grbit & 0x08) != 0) { shared = true; if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // It is a shared string formula formula = new SharedStringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else if (data[6] == 3 && data[12] == 0xff && data[13] == 0xff) { // We have a string which evaluates to null formula = new SharedStringFormulaRecord(t, excelFile, fr, es, nt, si, SharedStringFormulaRecord.EMPTY_STRING); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error int errorCode = data[8]; formula = new SharedErrorFormulaRecord(t, excelFile, errorCode, fr, es, nt, si); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { bool value = data[8] == 1 ? true : false; formula = new SharedBooleanFormulaRecord (t, excelFile, value, fr, es, nt, si); } else { // It is a numerical formula double value = DoubleHelper.getIEEEDouble(data, 6); SharedNumberFormulaRecord snfr = new SharedNumberFormulaRecord (t, excelFile, value, fr, es, nt, si); snfr.setNumberFormat(fr.getNumberFormat(getXFIndex())); formula = snfr; } return; } // microsoft and their goddam magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // we have a string formula = new StringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { // We have a bool formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t, fr, es, nt, si); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error formula = new ErrorFormulaRecord(t, fr, es, nt, si); } else if (data[6] == 3 && data[12] == 0xff && data[13] == 0xff) { // we have a string which evaluates to null formula = new StringFormulaRecord(t, fr, es, nt, si); } else { // it is most assuredly a number formula = new NumberFormulaRecord(t, fr, es, nt, si); } }
/** * Does the hard work of building up the object graph from the excel bytes * * @exception BiffException * @exception PasswordException if the workbook is password protected */ protected override void parse() { Record r = null; BOFRecord bof = new BOFRecord(excelFile.next()); workbookBof = bof; bofs++; if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (!bof.isWorkbookGlobals()) { throw new BiffException(BiffException.expectedGlobals); } ArrayList continueRecords = new ArrayList(); ArrayList localNames = new ArrayList(); nameTable = new ArrayList(); addInFunctions = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.getType() == Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array Record[] records = new Record[continueRecords.Count]; int pos = 0; foreach (Record record in continueRecords) { records[pos++] = record; } sharedStrings = new SSTRecord(r, records, settings); } else if (r.getType() == Type.FILEPASS) { throw new PasswordException(); } else if (r.getType() == Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r, settings, nameTable.Count); } else { nr = new NameRecord(r, settings, nameTable.Count, NameRecord.biff7); } // Add all local and global names to the name table in order to // preserve the indexing nameTable.Add(nr); if (nr.isGlobal()) { namedRecords.Add(nr.getName(), nr); } else { localNames.Add(nr); } } else if (r.getType() == Type.FONT) { FontRecord fr = null; if (bof.isBiff8()) { fr = new FontRecord(r, settings); } else { fr = new FontRecord(r, settings, FontRecord.biff7); } fonts.addFont(fr); } else if (r.getType() == Type.PALETTE) { CSharpJExcel.Jxl.Biff.PaletteRecord palette = new CSharpJExcel.Jxl.Biff.PaletteRecord(r); formattingRecords.setPalette(palette); } else if (r.getType() == Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.getType() == Type.FORMAT) { FormatRecord fr = null; if (bof.isBiff8()) { fr = new FormatRecord(r, settings, FormatRecord.biff8); } else { fr = new FormatRecord(r, settings, FormatRecord.biff7); } try { formattingRecords.addFormat(fr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false, e.Message); } } else if (r.getType() == Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) { xfr = new XFRecord(r, settings, XFRecord.biff8); } else { xfr = new XFRecord(r, settings, XFRecord.biff7); } try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false, e.Message); } } else if (r.getType() == Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) { br = new BoundsheetRecord(r, settings); } else { br = new BoundsheetRecord(r, BoundsheetRecord.biff7); } if (br.isSheet()) { boundsheets.Add(br); } else if (br.isChart() && !settings.getDrawingsDisabled()) { boundsheets.Add(br); } } else if (r.getType() == Type.EXTERNSHEET) { if (bof.isBiff8()) { externSheet = new ExternalSheetRecord(r, settings); } else { externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7); } } else if (r.getType() == Type.XCT) { XCTRecord xctr = new XCTRecord(r); xctRecords.Add(xctr); } else if (r.getType() == Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.setCharacterSet(cr.getCharacterSet()); } else if (r.getType() == Type.SUPBOOK) { Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { r.addContinueRecord(excelFile.next()); nextrec = excelFile.peek(); } SupbookRecord sr = new SupbookRecord(r, settings); supbooks.Add(sr); } else if (r.getType() == Type.EXTERNNAME) { ExternalNameRecord enr = new ExternalNameRecord(r, settings); if (enr.isAddInFunction()) { addInFunctions.Add(enr.getName()); } } else if (r.getType() == Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.isProtected(); } else if (r.getType() == Type.OBJPROJ) { doesContainMacros = true; } else if (r.getType() == Type.COUNTRY) { countryRecord = new CountryRecord(r); } else if (r.getType() == Type.MSODRAWINGGROUP) { if (!settings.getDrawingsDisabled()) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(Origin.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } } else if (r.getType() == Type.BUTTONPROPERTYSET) { buttonPropertySet = new ButtonPropertySetRecord(r); } else if (r.getType() == Type.EOF) { bofs--; } else if (r.getType() == Type.REFRESHALL) { RefreshAllRecord rfm = new RefreshAllRecord(r); settings.setRefreshAll(rfm.getRefreshAll()); } else if (r.getType() == Type.TEMPLATE) { TemplateRecord rfm = new TemplateRecord(r); settings.setTemplate(rfm.getTemplate()); } else if (r.getType() == Type.EXCEL9FILE) { Excel9FileRecord e9f = new Excel9FileRecord(r); settings.setExcel9File(e9f.getExcel9File()); } else if (r.getType() == Type.WINDOWPROTECT) { WindowProtectedRecord winp = new WindowProtectedRecord(r); settings.setWindowProtected(winp.getWindowProtected()); } else if (r.getType() == Type.HIDEOBJ) { HideobjRecord hobj = new HideobjRecord(r); settings.setHideobj(hobj.getHideMode()); } else if (r.getType() == Type.WRITEACCESS) { WriteAccessRecord war = new WriteAccessRecord(r, bof.isBiff8(), settings); settings.setWriteAccess(war.getWriteAccess()); } else { // logger.info("Unsupported record type: " + // Integer.toHexString(r.getCode())+"h"); } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) { bof = new BOFRecord(r); } } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && getNumberOfSheets() < boundsheets.Count) { if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (bof.isWorksheet()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else if (bof.isChart()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else { //logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.getType() != Type.EOF) { r = excelFile.next(); } } // The next record will normally be a BOF or empty padding until // the end of the block is reached. In exceptionally unlucky cases, // the last EOF will coincide with a block division, so we have to // check there is more data to retrieve. // Thanks to liamg for spotting this bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) { bof = new BOFRecord(r); } } } // Add all the local names to the specific sheets foreach (NameRecord nr in localNames) { if (nr.getBuiltInName() == null) { //logger.warn("Usage of a local non-builtin name"); } else if (nr.getBuiltInName() == BuiltInName.PRINT_AREA || nr.getBuiltInName() == BuiltInName.PRINT_TITLES) { // appears to use the internal tab number rather than the // external sheet index SheetImpl s = (SheetImpl)sheets[nr.getSheetRef() - 1]; s.addLocalName(nr); } } }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the available formats * @param si the sheet */ public BlankCell(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { }
/** * Constructs this string formula * * @param t the record * @param excelFile the excel file * @param fr the formatting record * @param es the external sheet * @param nt the workbook * @param si the sheet * @param ws the workbook settings */ public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, es, nt, si, excelFile.getPos()) { int pos = excelFile.getPos(); // Save the position in the excel file int filepos = excelFile.getPos(); // Look for the string record in one of the records after the // formula. Put a cap on it to prevent ednas Record nextRecord = excelFile.next(); int count = 0; while (nextRecord.getType() != Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4, " @ " + pos); byte[] stringData = nextRecord.getData(); // Read in any continuation records nextRecord = excelFile.peek(); while (nextRecord.getType() == Type.CONTINUE) { nextRecord = excelFile.next(); // move the pointer within the data byte[] d = new byte[stringData.Length + nextRecord.getLength() - 1]; System.Array.Copy(stringData, 0, d, 0, stringData.Length); System.Array.Copy(nextRecord.getData(), 1, d, stringData.Length, nextRecord.getLength() - 1); stringData = d; nextRecord = excelFile.peek(); } int chars = IntegerHelper.getInt(stringData[0], stringData[1]); bool unicode = false; int startpos = 3; if (stringData.Length == chars + 2) { // string might only consist of a one byte length indicator, instead // of the more normal 2 startpos = 2; unicode = false; } else if (stringData[2] == 0x1) { // unicode string, two byte length indicator startpos = 3; unicode = true; } else { // ascii string, two byte length indicator startpos = 3; unicode = false; } if (!unicode) { value = StringHelper.getString(stringData, chars, startpos, ws); } else { value = StringHelper.getUnicodeString(stringData, chars, startpos); } // Restore the position in the excel file, to enable the SHRFMLA // record to be picked up excelFile.setPos(filepos); }