private void Load(CompoundFile doc) { Stream stream; try { // see if workbook works stream = doc.OpenStream("Workbook"); } catch (IOException) { // see if book works, if not then leak the exception stream = doc.OpenStream("Book"); } SstRecord sst = null; /* long sstPos = 0; */ // record position dictionary SortedList<long, Biff> records = new SortedList<long, Biff>(); _styles = new StyleCollection(this); _formats = new FormatCollection(this); _fonts = new FontCollection(this); _palette = new Palette(this); _hyperLinks = new HyperLinkCollection(this); while (stream.Length - stream.Position >= GenericBiff.MinimumSize) { // capture the current stream position long pos = stream.Position; // decode the record if possible Biff record = GetCorrectRecord(new GenericBiff(stream), stream, sst); // capture // shared string table if (record is SstRecord) { Debug.Assert(sst == null); sst = (SstRecord)record; /* sstPos = pos; */ } // formatting records else if (record is FormatRecord) { FormatRecord f = (FormatRecord)record; _formats.Add(f.Index, new Format(this, f)); } else if (record is FontRecord) _fonts.Add(new Font(this, (FontRecord)record)); else if (record is PaletteRecord) _palette.Initialize((PaletteRecord)record); else if (record is XfRecord) _styles.Add(new Style(this, (XfRecord)record)); else if (record is HyperLinkRecord) _hyperLinks.Add((HyperLinkRecord)record); Debug.Assert(!records.ContainsKey(pos)); // store the position and corresponding record records[pos] = record; } // generate the worksheets _sheets = new WorksheetCollection(); foreach (Biff record in records.Values) { if (record is BoundSheetRecord) _sheets.Add(new Worksheet(this, (BoundSheetRecord)record, records)); } }
internal Worksheet(Workbook wb, BoundSheetRecord sheet, SortedList<long, Biff> records) : base(wb) { _name = sheet.Name; int idx = records.IndexOfKey((long)sheet.BofPos); _hyperlinks = new HyperLinkCollection(wb); for (int i = idx + 1; i < records.Count; ++i) { Biff biff = records.Values[i]; if (biff is HyperLinkRecord) _hyperlinks.Add((HyperLinkRecord)biff); else if (biff is EofRecord) break; } BofRecord bof = (BofRecord)records.Values[idx++]; Biff seeker = records.Values[idx++]; while (!(seeker is IndexRecord)) seeker = records.Values[idx++]; IndexRecord index = (IndexRecord)seeker; _rows = new RowCollection(wb); foreach (uint indexPos in index.Rows) { long dbCellPos = indexPos; int dbCellIdx = records.IndexOfKey(dbCellPos); DbCellRecord dbCell = (DbCellRecord)records[dbCellPos]; if (dbCell.RowOffset > 0) { long rowPos = dbCellPos - dbCell.RowOffset; int recIndex = records.IndexOfKey(rowPos); Debug.Assert(recIndex != -1); Biff record = records.Values[recIndex++]; while (record is RowRecord) { RowRecord row = (RowRecord)record; Row currentRow = new Row(Workbook, row); _rows.Add(row.RowNumber, currentRow); record = records.Values[recIndex++]; } while (recIndex <= dbCellIdx) { if (!(record is CellRecord)) { record = records.Values[recIndex++]; continue; } CellRecord thecell = (CellRecord)record; Row currentRow = _rows[thecell.Row]; if (thecell is SingleColCellRecord) { SingleColCellRecord cell = (SingleColCellRecord)thecell; object val = cell.Value; Cell newCell = new Cell(Workbook, val); if (cell is RowColXfCellRecord) { RowColXfCellRecord xfCell = (RowColXfCellRecord)cell; Style style = Workbook.Styles[xfCell.Xf]; Debug.Assert(style != null); newCell.Style = style; } currentRow.Cells.Add((byte)cell.Col, newCell); } else { MultipleColCellRecord cells = (MultipleColCellRecord)thecell; for (ushort i = cells.FirstCol; i <= cells.LastCol; ++i) { object val = cells.GetValue(i); if (val != null) { Cell newCell = null; if (val is RkRec) { RkRec rk = (RkRec)val; newCell = new Cell(Workbook, rk.Value); Style style = Workbook.Styles[rk.Xf]; Debug.Assert(style != null); newCell.Style = style; } else newCell = new Cell(Workbook, val); currentRow.Cells.Add((byte)i, newCell); } } } record = records.Values[recIndex++]; } } } }