private void ReadBytes(Bytes bytes, BytesReadCallback bytesReadCallback) { if (bytes == null) { throw new ArgumentNullException("bytes"); } if (bytes.Length == 0) { throw new ArgumentException("can't be zero-length", "bytes"); } //The XF's read in won't necessarily have the same ID (index) once added to this Workbook, //so we need to keep the cross-reference list for re-assignment as we read in the cell records later SortedList <ushort, ushort> xfIdLookups = new SortedList <ushort, ushort>(); List <Record> records = Record.GetAll(bytes); List <Record> fontRecords = new List <Record>(); List <Record> formatRecords = new List <Record>(); List <Record> xfRecords = new List <Record>(); List <Record> boundSheetRecords = new List <Record>(); Record sstRecord = Record.Empty; SortedList <int, List <Record> > sheetRecords = new SortedList <int, List <Record> >(); int sheetIndex = -1; foreach (Record record in records) { if (sheetIndex >= 0) { if (!sheetRecords.ContainsKey(sheetIndex)) { sheetRecords[sheetIndex] = new List <Record>(); } sheetRecords[sheetIndex].Add(record); if (record.RID == RID.EOF) { sheetIndex++; } } else if (record.RID == RID.FONT) { fontRecords.Add(record); } else if (record.RID == RID.FORMAT) { formatRecords.Add(record); } else if (record.RID == RID.XF) { xfRecords.Add(record); } else if (record.RID == RID.BOUNDSHEET) { boundSheetRecords.Add(record); } else if (record.RID == RID.SST) { sstRecord = record; } else if (record.RID == RID.EOF) { sheetIndex++; } } SortedList <ushort, string> formats = new SortedList <ushort, string>(); ushort index = 0; foreach (Record record in fontRecords) { Font font = new Font(_doc, record.Data); this.Fonts.Add(font); } foreach (Record record in formatRecords) { Bytes recordData = record.Data; string format = UnicodeBytes.Read(recordData.Get(2, recordData.Length - 2), 16); index = BitConverter.ToUInt16(recordData.Get(2).ByteArray, 0); formats[index] = format; this.Formats.Add(format); } index = 0; for (index = 0; index < xfRecords.Count; index++) { Record record = xfRecords[index]; Bytes recordData = record.Data; ushort fontIndex = BitConverter.ToUInt16(recordData.Get(0, 2).ByteArray, 0); ushort formatIndex = BitConverter.ToUInt16(recordData.Get(2, 2).ByteArray, 0); //ushort styleIndex = BitConverter.ToUInt16(recordData.Get(4, 2)) //TODO: Defaults to default font. Should it? NOTE: This is encountered with TestReferenceFile BlankBudgetWorksheet.xls Font font = fontIndex < _fonts.Count ? _fonts[fontIndex] : _fonts[0]; string format; if (formats.ContainsKey(formatIndex)) { format = formats[formatIndex]; } else if (_formats.ContainsKey(formatIndex)) { format = _formats[formatIndex]; } else { throw new Exception(string.Format("Format {0} not found in read FORMAT records or standard/default FORMAT records.", formatIndex)); } xfIdLookups[index] = this.XFs.Add(new XF(_doc, record.Data, font, format)); } this.XFs.XfIdxLookups = xfIdLookups; if (sstRecord != Record.Empty) { this.SharedStringTable.ReadBytes(sstRecord); } if (bytesReadCallback != null) { bytesReadCallback(records); } for (int i = 0; i < boundSheetRecords.Count; i++) { _worksheets.Add(boundSheetRecords[i], sheetRecords[i]); } }