Beispiel #1
0
        internal FormulaRecord(Record formulaRecord, Record stringRecord)
            : base()
        {
            _rid = formulaRecord.RID;
            _data = formulaRecord.Data;
            _continues = formulaRecord.Continues;

            StringRecord = stringRecord;
        }
Beispiel #2
0
        internal static string Read(Record record, int lengthBits, ref int continueIndex, ref ushort offset)
        {
            string text = string.Empty;

            ReadState state = new ReadState(record, lengthBits, continueIndex, offset);
            Read(state);
            continueIndex = state.ContinueIndex;
            offset = state.Offset;

            return new string(state.CharactersRead.ToArray());
        }
Beispiel #3
0
        private Bytes INDEX(int baseLength)
        {
            Bytes index = new Bytes();

            //Not used
            index.Append(new byte[] { 0x00, 0x00, 0x00, 0x00 });

            //Index to first used row (0-based)
            index.Append(BitConverter.GetBytes(_rows.MinRow - 1));

            //Index to first row of unused tail of sheet(last row + 1, 0-based)
            index.Append(BitConverter.GetBytes(_rows.MaxRow));

            //Absolute stream position of the DEFCOLWIDTH record
            //TODO: Implement Worksheet.INDEX Absolute stream position of the DEFCOLWIDTH record (not necessary)
            index.Append(BitConverter.GetBytes((uint)0));

            for (int i = 1; i < _dbCellOffsets.Length; i++)
            {
                index.Append(BitConverter.GetBytes((uint)(baseLength + _dbCellOffsets[i])));
            }

            return(Record.GetBytes(RID.INDEX, index));
        }
Beispiel #4
0
 private static string Read(Record record, int lengthBits, ushort offset)
 {
     int continueIndex = -1; //throw away
     return Read(record, lengthBits, ref continueIndex, ref offset);
 }
Beispiel #5
0
            public ReadState(Record record, int lengthBits, int continueIndex, ushort offset)
            {
                LengthBits = lengthBits;
                Record = record;
                ContinueIndex = continueIndex;
                Offset = offset;

                Bytes data = GetRecordData();

                if (LengthBits == 8)
                {
                    TotalCharacters = data.Get(offset, 1).ByteArray[0];
                    Offset++;
                }
                else
                {
                    TotalCharacters = data.Get(offset, 2).GetBits().ToUInt16();
                    Offset += 2;
                }

                ReadOptionsFlags();

                HasAsianPhonetics = (OptionsFlags & 0x04) == 0x04;
                HasRichTextSettings = (OptionsFlags & 0x08) == 0x08;

                if (HasRichTextSettings)
                {
                    FormattingRunCount = BitConverter.ToUInt16(data.Get(Offset, 2).ByteArray, 0);
                    Offset += 2;
                    //bytesRemaining += (ushort)(4 * formattingRuns);
                    //NOTE: When implementing Rich Text, remember to add total length of formating runs to bytesRead
                    //throw new NotSupportedException("Rich Text text values in cells are not yet supported");
                }

                if (HasAsianPhonetics)
                {
                    PhoneticSettingsByteCount = BitConverter.ToUInt32(data.Get(Offset, 4).ByteArray, 0);
                    Offset += 4;
                    //NOTE: When implementing Asian Text, remember to add total length of Asian Phonetic Settings Block to bytesRead
                    //throw new NotSupportedException("Asian Phonetic text values in cells are not yet supported");
                }
            }
Beispiel #6
0
 internal static string Read(Bytes bytes, int lengthBits)
 {
     Record record = new Record(RID.Empty, bytes);
     return Read(record, lengthBits, 0);
 }
Beispiel #7
0
        internal Worksheet(XlsDocument doc, Record boundSheet, List<Record> sheetRecords)
            : this(doc)
        {
            byte[] byteArray = boundSheet.Data.ByteArray;

            byte visibility = byteArray[4];
            if (visibility == 0x00)
                _visibility = WorksheetVisibilities.Visible;
            else if (visibility == 0x01)
                _visibility = WorksheetVisibilities.Hidden;
            else if (visibility == 0x02)
                _visibility = WorksheetVisibilities.StrongHidden;
            else
                throw new Exception(string.Format("Unknown Visibility {0}", visibility));

            byte type = byteArray[5];
            if (type == 0x00)
                _sheettype = WorksheetTypes.Worksheet;
            else if (type == 0x02)
                _sheettype = WorksheetTypes.Chart;
            else if (type == 0x06)
                _sheettype = WorksheetTypes.VBModule;
            else
                throw new Exception(string.Format("Unknown Sheet Type {0}", type));

            List<Record> rowRecords = new List<Record>();
            List<Record> cellRecords = new List<Record>();
            List<Record> noteRecords = new List<Record>();

            for (int i = 0; i < sheetRecords.Count; i++)
            {
                Record record = sheetRecords[i];
                if (record.IsCellRecord())
                {
                    if (record.RID == RID.FORMULA)
                    {
                        Record formulaStringRecord = null;
                        if ((i + i) < sheetRecords.Count)
                        {
                            formulaStringRecord = sheetRecords[i + 1];
                            if (formulaStringRecord.RID != RID.STRING)
                                formulaStringRecord = null;
                        }
                        record = new FormulaRecord(record, formulaStringRecord);
                    }

                    cellRecords.Add(record);
                }
                else if (record.RID == RID.ROW)
                    rowRecords.Add(record);
                else if (record.RID == RID.NOTE)
                    noteRecords.Add(record);
            }

            //Add the Rows first so they exist for adding the Cells
            foreach (Record rowRecord in rowRecords)
            {
                Bytes rowBytes = rowRecord.Data;
                ushort rowIndex = rowBytes.Get(0, 2).GetBits().ToUInt16();
                Row row = Rows.AddRow(rowIndex);
                bool isDefaultHeight = rowBytes.Get(6, 2).GetBits().Values[15];
                ushort height = 0;
                if (!isDefaultHeight)
                {
                    height = rowBytes.Get(6, 2).GetBits().Get(0, 14).ToUInt16();
                    //TODO: Set height on Row when reading (after Row Height implemented)
                }
                bool defaultsWritten = (rowBytes.Get(10, 1).ByteArray[0] == 0x01);
                if (defaultsWritten)
                {
                    //TODO: Read ROW record defaults
                }
            }

            foreach (Record record in cellRecords)
                AddCells(record);

            foreach (Record record in noteRecords)
                AddNote(record);

            _name = UnicodeBytes.Read(boundSheet.Data.Get(6, boundSheet.Data.Length - 6), 8);
        }
Beispiel #8
0
 private void AddNote(Record record)
 {
     Bytes bytes = record.Data;
     ushort rowIndex = bytes.Get(0, 2).GetBits().ToUInt16();
     ushort colIndex = bytes.Get(2, 2).GetBits().ToUInt16();
     Bytes options = bytes.Get(4, 2);
     ushort objId = bytes.Get(6, 2).GetBits().ToUInt16();
     string authorName = UnicodeBytes.Read(bytes.Get(8, bytes.Length - 8), 16);
     Debugger.Break();
 }
Beispiel #9
0
        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]);
            }
        }
Beispiel #10
0
        internal Worksheet(XlsDocument doc, Record boundSheet, List <Record> sheetRecords) : this(doc)
        {
            byte[] byteArray = boundSheet.Data.ByteArray;

            byte visibility = byteArray[4];
            if (visibility == 0x00)
            {
                _visibility = WorksheetVisibilities.Visible;
            }
            else if (visibility == 0x01)
            {
                _visibility = WorksheetVisibilities.Hidden;
            }
            else if (visibility == 0x02)
            {
                _visibility = WorksheetVisibilities.StrongHidden;
            }
            else
            {
                throw new ApplicationException(string.Format("Unknown Visibility {0}", visibility));
            }

            byte type = byteArray[5];
            if (type == 0x00)
            {
                _sheettype = WorksheetTypes.Worksheet;
            }
            else if (type == 0x02)
            {
                _sheettype = WorksheetTypes.Chart;
            }
            else if (type == 0x06)
            {
                _sheettype = WorksheetTypes.VBModule;
            }
            else
            {
                throw new ApplicationException(string.Format("Unknown Sheet Type {0}", type));
            }

            List <Record> rowRecords  = new List <Record>();
            List <Record> cellRecords = new List <Record>();

            for (int i = 0; i < sheetRecords.Count; i++)
            {
                Record record = sheetRecords[i];
                if (record.IsCellRecord())
                {
                    if (record.RID == RID.FORMULA)
                    {
                        Record formulaStringRecord = null;
                        if ((i + i) < sheetRecords.Count)
                        {
                            formulaStringRecord = sheetRecords[i + 1];
                            if (formulaStringRecord.RID != RID.STRING)
                            {
                                formulaStringRecord = null;
                            }
                        }
                        record = new FormulaRecord(record, formulaStringRecord);
                    }

                    cellRecords.Add(record);
                }
                else if (record.RID == RID.ROW)
                {
                    rowRecords.Add(record);
                }
            }

            //Add the Rows first so they exist for adding the Cells
            foreach (Record rowRecord in rowRecords)
            {
                Bytes  rowBytes        = rowRecord.Data;
                ushort rowIndex        = rowBytes.Get(0, 2).GetBits().ToUInt16();
                Row    row             = Rows.AddRow(rowIndex);
                bool   isDefaultHeight = rowBytes.Get(6, 2).GetBits().Values[15];
                ushort height          = 0;
                if (!isDefaultHeight)
                {
                    height = rowBytes.Get(6, 2).GetBits().Get(0, 14).ToUInt16();
                    //TODO: Set height on Row when reading (after Row Height implemented)
                }
                bool defaultsWritten = (rowBytes.Get(10, 1).ByteArray[0] == 0x01);
                if (defaultsWritten)
                {
                    //TODO: Read ROW record defaults
                }
            }

            foreach (Record record in cellRecords)
            {
                AddCells(record);
            }

            _name = UnicodeBytes.Read(boundSheet.Data.Get(6, boundSheet.Data.Length - 6), 8);
        }
Beispiel #11
0
        private void AddCells(Record record)
        {
            Bytes  bytes        = record.Data;
            ushort rowIndex     = bytes.Get(0, 2).GetBits().ToUInt16();
            ushort colIndex     = bytes.Get(2, 2).GetBits().ToUInt16();
            ushort lastColIndex = colIndex;
            ushort offset       = 4;

            byte[] rid     = record.RID;
            bool   isMulti = false;

            if (rid == RID.MULBLANK)
            {
                isMulti = true;
                rid     = RID.BLANK;
            }
            else if (rid == RID.MULRK)
            {
                isMulti = true;
                rid     = RID.RK;
            }

            if (isMulti)
            {
                lastColIndex = bytes.Get(bytes.Length - 2, 2).GetBits().ToUInt16();
            }


            while (colIndex <= lastColIndex)
            {
                Cell   cell    = Cells.Add((ushort)(rowIndex + 1), (ushort)(colIndex + 1));
                ushort xfIndex = bytes.Get(offset, 2).GetBits().ToUInt16();
                offset += 2;

                Bytes data;
                if (rid == RID.BLANK)
                {
                    data = new Bytes();
                }
                else if (rid == RID.RK)
                {
                    data    = bytes.Get(offset, 4);
                    offset += 4;
                    cell.SetValue(rid, data);
                }
                else
                {
                    data = bytes.Get(offset, bytes.Length - offset);
                    if (rid == RID.FORMULA)
                    {
                        FormulaRecord formulaRecord = record as FormulaRecord;
                        cell.SetFormula(data, formulaRecord.StringRecord);
                    }
                    else
                    {
                        cell.SetValue(rid, data);
                    }
                }
                colIndex++;
            }
        }
Beispiel #12
0
 private void DecodeFORMULA(Bytes data, Record stringRecord)
 {
     //TODO: Read in formula properties
     if (stringRecord != null)
         _value = UnicodeBytes.Read(stringRecord.Data, 16);
     _type = CellTypes.Formula;
 }
Beispiel #13
0
 internal void SetFormula(Bytes data, Record stringRecord)
 {
     DecodeFORMULA(data, stringRecord);
 }
Beispiel #14
0
 // Token: 0x06000151 RID: 337 RVA: 0x000076F2 File Offset: 0x000066F2
 internal void SetFormula(Bytes data, Record stringRecord)
 {
     this.DecodeFORMULA(data, stringRecord);
 }
Beispiel #15
0
        private void AddCells(Record record)
        {
            Bytes bytes = record.Data;
            ushort rowIndex = bytes.Get(0, 2).GetBits().ToUInt16();
            ushort colIndex = bytes.Get(2, 2).GetBits().ToUInt16();
            ushort lastColIndex = colIndex;
            ushort offset = 4;

            byte[] rid = record.RID;
            bool isMulti = false;

            if (rid == RID.MULBLANK)
            {
                isMulti = true;
                rid = RID.BLANK;
            }
            else if (rid == RID.MULRK)
            {
                isMulti = true;
                rid = RID.RK;
            }

            if (isMulti)
                lastColIndex = bytes.Get(bytes.Length - 2, 2).GetBits().ToUInt16();

            while (colIndex <= lastColIndex)
            {
                Cell cell = Cells.Add((ushort)(rowIndex + 1), (ushort)(colIndex + 1));
                ushort xfIndex = bytes.Get(offset, 2).GetBits().ToUInt16();
                ushort index = _doc.Workbook.XFs.XfIdxLookups[xfIndex];
                cell.SetXfIndex(index);
                offset += 2;

                Bytes data;
                if (rid == RID.BLANK)
                    data = new Bytes();
                else if (rid == RID.RK)
                {
                    data = bytes.Get(offset, 4);
                    offset += 4;
                    cell.SetValue(rid, data);
                }
                else
                {
                    data = bytes.Get(offset, bytes.Length - offset);
                    if (rid == RID.FORMULA)
                    {
                        FormulaRecord formulaRecord = record as FormulaRecord;
                        cell.SetFormula(data, formulaRecord.StringRecord);
                    }
                    else
                        cell.SetValue(rid, data);
                }
                colIndex++;
            }
        }
Beispiel #16
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static List<Record> GetAll(Bytes stream)
        {
            int i = 0;
            List<Record> records = new List<Record>();
            Record lastNonContinue = Record.Empty;
            while (i < (stream.Length - 4))
            {
                byte[] rid = org.in2bits.MyXls.RID.ByteArray(stream.Get(i, 2).ByteArray);
                Bytes data = new Bytes();
                if (rid == MyXls.RID.Empty)
                    break;
                int length = BitConverter.ToUInt16(stream.Get(i + 2, 2).ByteArray, 0);
                data = stream.Get(i + 4, length);
                Record record = new Record(rid, data);
                i += (4 + length);
                if (rid == MyXls.RID.CONTINUE)
                {
                    if (lastNonContinue == Record.Empty)
                        throw new Exception("Found CONTINUE record without previous/parent record.");

                    lastNonContinue.Continues.Add(record);
                }
                else
                {
                    lastNonContinue = record;
                    records.Add(record);
                }
            }

            return records;
        }
Beispiel #17
0
 //TODO: Implement Rich Text Value support
 //TODO: Implement Asian Text Value support
 internal void ReadBytes(Record sstRecord)
 {
     uint totalStrings = sstRecord.Data.Get(0, 4).GetBits().ToUInt32();
     uint uniqueStrings = sstRecord.Data.Get(4, 4).GetBits().ToUInt32();
     int stringIndex = 0;
     ushort offset = 8;
     int continueIndex = -1;
     while (stringIndex < uniqueStrings)
     {
         string sharedString = UnicodeBytes.Read(sstRecord, 16, ref continueIndex, ref offset);
         Add(sharedString);
         stringIndex++;
     }
     _countAll = totalStrings;
 }