Example #1
0
        /// <summary>
        /// Find how many rows to read at a time and their offset in the file.
        /// If rows are stored sequentially in the file, returns a block size of up to 32 rows.
        /// If rows are stored non-sequentially, the block size may extend up to the entire worksheet stream
        /// </summary>
        private void GetBlockSize(int startRow, out int blockRowCount, out int minOffset, out int maxOffset)
        {
            minOffset = int.MaxValue;
            maxOffset = int.MinValue;

            var i = 0;

            blockRowCount = Math.Min(32, RowCount - startRow);

            while (i < blockRowCount)
            {
                if (RowOffsetMap.TryGetValue(startRow + i, out var rowOffset))
                {
                    minOffset = Math.Min(rowOffset.MinCellOffset, minOffset);
                    maxOffset = Math.Max(rowOffset.MaxCellOffset, maxOffset);

                    if (rowOffset.MaxOverlapRowIndex != int.MinValue)
                    {
                        var maxOverlapRowCount = rowOffset.MaxOverlapRowIndex + 1;
                        blockRowCount = Math.Max(blockRowCount, maxOverlapRowCount - startRow);
                    }
                }

                i++;
            }
        }
Example #2
0
        private XlsRowBlock ReadNextBlock(XlsBiffStream biffStream, int startRow, int rows, int minOffset, int maxOffset)
        {
            var result = new XlsRowBlock {
                Rows = new Dictionary <int, Row>()
            };

            // Ensure rows with physical records are initialized with height
            for (var i = 0; i < rows; i++)
            {
                if (RowOffsetMap.TryGetValue(startRow + i, out _))
                {
                    EnsureRow(result, startRow + i);
                }
            }

            if (minOffset == int.MaxValue)
            {
                return(result);
            }

            biffStream.Position = minOffset;

            XlsBiffRecord rec;
            XlsBiffRecord ixfe = null;

            while (biffStream.Position <= maxOffset && (rec = biffStream.Read()) != null)
            {
                if (rec.Id == BIFFRECORDTYPE.IXFE)
                {
                    // BIFF2: If cell.xformat == 63, this contains the actual XF index >= 63
                    ixfe = rec;
                }

                if (rec.IsCell)
                {
                    var cell       = (XlsBiffBlankCell)rec;
                    var currentRow = EnsureRow(result, cell.RowIndex);

                    if (cell.Id == BIFFRECORDTYPE.MULRK)
                    {
                        var cellValues = ReadMultiCell(cell);
                        currentRow.Cells.AddRange(cellValues);
                    }
                    else
                    {
                        var xfIndex   = GetXfIndexForCell(cell, ixfe);
                        var cellValue = ReadSingleCell(biffStream, cell, xfIndex);
                        currentRow.Cells.Add(cellValue);
                    }

                    ixfe = null;
                }
            }

            return(result);
        }
Example #3
0
        private void SetMinMaxRow(int rowIndex, XlsBiffRow row)
        {
            if (!RowOffsetMap.TryGetValue(rowIndex, out var rowOffset))
            {
                rowOffset = new XlsRowOffset();
                rowOffset.MinCellOffset      = int.MaxValue;
                rowOffset.MaxCellOffset      = int.MinValue;
                rowOffset.MaxOverlapRowIndex = int.MinValue;
                RowOffsetMap.Add(rowIndex, rowOffset);
            }

            rowOffset.Record = row;
        }
Example #4
0
        private void SetMinMaxRowOffset(int rowIndex, int recordOffset, int maxOverlapRow)
        {
            if (!RowOffsetMap.TryGetValue(rowIndex, out var rowOffset))
            {
                rowOffset = new XlsRowOffset();
                rowOffset.MinCellOffset      = int.MaxValue;
                rowOffset.MaxCellOffset      = int.MinValue;
                rowOffset.MaxOverlapRowIndex = int.MinValue;
                RowOffsetMap.Add(rowIndex, rowOffset);
            }

            rowOffset.MinCellOffset      = Math.Min(recordOffset, rowOffset.MinCellOffset);
            rowOffset.MaxCellOffset      = Math.Max(recordOffset, rowOffset.MaxCellOffset);
            rowOffset.MaxOverlapRowIndex = Math.Max(maxOverlapRow, rowOffset.MaxOverlapRowIndex);
        }
Example #5
0
        private Row EnsureRow(XlsRowBlock result, int rowIndex)
        {
            if (!result.Rows.TryGetValue(rowIndex, out var currentRow))
            {
                var height = DefaultRowHeight / 20.0;
                if (RowOffsetMap.TryGetValue(rowIndex, out var rowOffset) && rowOffset.Record != null)
                {
                    height = (rowOffset.Record.UseDefaultRowHeight ? DefaultRowHeight : rowOffset.Record.RowHeight) / 20.0;
                }

                currentRow = new Row(rowIndex, height, new List <Cell>());

                result.Rows.Add(rowIndex, currentRow);
            }

            return(currentRow);
        }