/// <summary> Constructor /// /// </summary> /// <param name="f">the excel file /// </param> /// <param name="sst">the shared string table /// </param> /// <param name="fr">formatting records /// </param> /// <param name="sb">the bof record which indicates the start of the sheet /// </param> /// <param name="wb">the bof record which indicates the start of the sheet /// </param> /// <param name="nf">the 1904 flag /// </param> /// <param name="wp">the workbook which this sheet belongs to /// </param> /// <exception cref=""> BiffException /// </exception> internal SheetImpl(File f, SSTRecord sst, FormattingRecords fr, BOFRecord sb, BOFRecord wb, bool nf, WorkbookParser wp) { excelFile = f; sharedStrings = sst; formattingRecords = fr; sheetBof = sb; workbookBof = wb; columnInfosArray = new ArrayList(); sharedFormulas = new ArrayList(); hyperlinks = new ArrayList(); rowProperties = new ArrayList(10); columnInfosInitialized = false; rowRecordsInitialized = false; nineteenFour = nf; workbook = wp; workbookSettings = workbook.Settings; // Mark the position in the stream, and then skip on until the end startPosition = f.Pos; if (sheetBof.isChart()) { // Set the start pos to include the bof so the sheet reader can handle it startPosition -= (sheetBof.Length + 4); } Record r = null; int bofs = 1; while (bofs >= 1) { r = f.next(); // use this form for quick performance if (r.Code == NExcel.Biff.Type.EOF.Value) { bofs--; } if (r.Code == NExcel.Biff.Type.BOF.Value) { bofs++; } } }
/// <summary> Constructor /// /// </summary> /// <param name="fr">the formatting records /// </param> /// <param name="sst">the shared string table /// </param> /// <param name="f">the excel file /// </param> /// <param name="sb">the bof record which indicates the start of the sheet /// </param> /// <param name="wb">the bof record which indicates the start of the sheet /// </param> /// <param name="wp">the workbook which this sheet belongs to /// </param> /// <param name="sp">the start position of the sheet bof in the excel file /// </param> /// <param name="sh">the sheet /// </param> /// <param name="nf">1904 date record flag /// </param> /// <exception cref=""> BiffException /// </exception> internal SheetReader(File f, SSTRecord sst, FormattingRecords fr, BOFRecord sb, BOFRecord wb, bool nf, WorkbookParser wp, int sp, SheetImpl sh) { excelFile = f; sharedStrings = sst; formattingRecords = fr; sheetBof = sb; workbookBof = wb; columnInfosArray = new ArrayList(); sharedFormulas = new ArrayList(); hyperlinks = new ArrayList(); rowProperties = new ArrayList(10); charts = new ArrayList(); drawings = new ArrayList(); nineteenFour = nf; workbook = wp; startPosition = sp; sheet = sh; settings = new SheetSettings(); workbookSettings = workbook.Settings; }
/// <summary> Does the hard work of building up the object graph from the excel bytes /// /// </summary> /// <exception cref=""> BiffException /// </exception> /// <exception cref=""> PasswordException if the workbook is password protected /// </exception> protected internal 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(); nameTable = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array System.Object[] rec = continueRecords.ToArray(); Record[] records = new Record[rec.Length]; Array.Copy(rec, 0, records, 0, rec.Length); sharedStrings = new SSTRecord(r, records, settings); } else if (r.Type == NExcel.Biff.Type.FILEPASS) { throw new PasswordException(); } else if (r.Type == NExcel.Biff.Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r, settings, namedRecords.Count); } else { nr = new NameRecord(r, settings, namedRecords.Count, NameRecord.biff7); } namedRecords[nr.Name] = nr; nameTable.Add(nr); } else if (r.Type == NExcel.Biff.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.Type == NExcel.Biff.Type.PALETTE) { NExcel.Biff.PaletteRecord palette = new NExcel.Biff.PaletteRecord(r); formattingRecords.Palette = palette; } else if (r.Type == NExcel.Biff.Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.Type == NExcel.Biff.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.getMessage()); Assert.verify(false, "This should not happen. 64"); } } else if (r.Type == NExcel.Biff.Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) { xfr = new XFRecord(r, XFRecord.biff8); } else { xfr = new XFRecord(r, XFRecord.biff7); } try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out // Assert.verify(false, e.getMessage()); Assert.verify(false, "This should not happen. 59"); } } else if (r.Type == NExcel.Biff.Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) { br = new BoundsheetRecord(r); } else { br = new BoundsheetRecord(r, BoundsheetRecord.biff7); } if (br.isSheet() || br.Chart) { boundsheets.Add(br); } } else if (r.Type == NExcel.Biff.Type.EXTERNSHEET) { if (bof.isBiff8()) { externSheet = new ExternalSheetRecord(r, settings); } else { externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7); } } else if (r.Type == NExcel.Biff.Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.CharacterSet = cr.CharacterSet; } else if (r.Type == NExcel.Biff.Type.SUPBOOK) { SupbookRecord sr = new SupbookRecord(r, settings); supbooks.Add(sr); } else if (r.Type == NExcel.Biff.Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.IsProtected(); } else if (r.Type == NExcel.Biff.Type.MSODRAWINGGROUP) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(DrawingGroup.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } else if (r.Type == NExcel.Biff.Type.EOF) { bofs--; } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && NumberOfSheets < 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[NumberOfSheets]; s.setName(br.Name); s.Hidden = 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[NumberOfSheets]; s.setName(br.Name); s.Hidden = br.isHidden(); addSheet(s); } else { logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.Type != NExcel.Biff.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.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } } }
/// <summary> Constructor. Retrieves the index from the raw data and looks it up /// in the shared string table /// /// </summary> /// <param name="stringTable">the shared string table /// </param> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> public LabelSSTRecord(Record t, SSTRecord stringTable, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { sbyte[] data = getRecord().Data; index = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); _Value = stringTable.getString(index); }