예제 #1
0
        protected override void OnPrintPage(PrintPageEventArgs e)
        {
            base.OnPrintPage(e);
            if (m_PageCount == 0)
            {
                m_HeaderHeight = this.GetHeaderHeight(e.Graphics);
                m_TitleHeight  = this.GetTitleHeight(e.Graphics);
                m_FooterHeight = this.GetFooterHeight(e.Graphics);
                m_PageCount    = this.PrecalculatePageCount(e);
                m_PageNo       = 1;
            }

            if (m_RangeToPrint.IsEmpty())
            {
                return;
            }

            if (m_BorderPen == null)
            {
                m_BorderPen = new Pen(Color.Black);
            }

            RectangleF area = new RectangleF(e.MarginBounds.Left,
                                             e.MarginBounds.Top + m_HeaderHeight + (m_NextRowToPrint == RangeToPrint.Start.Row ? m_TitleHeight : 0),
                                             e.MarginBounds.Width,
                                             e.MarginBounds.Height - m_HeaderHeight - (m_NextRowToPrint == RangeToPrint.Start.Row ? m_TitleHeight : 0) - m_FooterHeight);

            this.DrawHeader(e.Graphics, new RectangleF(e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, m_HeaderHeight),
                            m_PageNo, m_PageCount);

            if (m_PageNo == 1)
            {
                this.DrawTitle(e.Graphics, new RectangleF(e.MarginBounds.Left, e.MarginBounds.Top + m_HeaderHeight, e.MarginBounds.Width, m_TitleHeight),
                               m_PageNo, m_PageCount);
            }

            List <int>      columnHasTopBorder = new List <int>();
            List <int>      rowHasLeftBorder   = new List <int>();
            RangeCollection printedRanges      = new RangeCollection();

            int pageFirstRow    = m_NextRowToPrint;
            int pageFirstColumn = m_NextColumnToPrint;
            int pageLastColumn  = RangeToPrint.End.Column;

            // Pre-calculate width of the table in current page
            float pageColumnWidth = 0;

            for (int i = m_NextColumnToPrint; i <= RangeToPrint.End.Column; i++)
            {
                float colWidth = this.GetColumnWidth(e.Graphics, i);
                if (i == m_NextColumnToPrint && colWidth > area.Width)
                {
                    colWidth = area.Width;
                }
                if (pageColumnWidth + colWidth <= area.Width)
                {
                    pageColumnWidth += colWidth;
                }
                else
                {
                    break;
                }
            }

            // Support for fixed row repeat
            if (RepeatFixedRows && m_Grid.ActualFixedRows > RangeToPrint.Start.Row)
            {
                m_NextRowToPrint = RangeToPrint.Start.Row;
            }

            float curY = area.Top;

            while (m_NextRowToPrint <= RangeToPrint.End.Row)
            {
                // If repeated rows are printed, resume printing next rows
                if (RepeatFixedRows && m_NextRowToPrint >= m_Grid.ActualFixedRows && m_NextRowToPrint < pageFirstRow)
                {
                    m_NextRowToPrint = pageFirstRow;
                }
                float rowHeight = this.GetRowHeight(e.Graphics, m_NextRowToPrint);
                // Check if row fits in current page
                if (curY + rowHeight > area.Bottom)
                {
                    break;
                }
                float curX = area.Left;
                while (m_NextColumnToPrint <= pageLastColumn)
                {
                    float colWidth = this.GetColumnWidth(e.Graphics, m_NextColumnToPrint);
                    // Check if column fits in current page
                    if (curX + colWidth > area.Right)
                    {
                        // If single column does not fit in page, force it
                        if (m_NextColumnToPrint == pageFirstColumn)
                        {
                            colWidth = area.Right - curX;
                        }
                        else
                        {
                            pageLastColumn = m_NextColumnToPrint - 1;
                            break;
                        }
                    }
                    RectangleF cellRectangle;
                    Position   pos   = new Position(m_NextRowToPrint, m_NextColumnToPrint);
                    GridRange  range = m_Grid.PositionToCellRange(pos);

                    // Check if cell is spanned
                    if (range.ColumnsCount > 1 || range.RowsCount > 1)
                    {
                        Size rangeSize = m_Grid.RangeToSize(range);
                        // Is the first position, draw allways
                        if (range.Start == pos)
                        {
                            cellRectangle = new RectangleF(curX, curY, rangeSize.Width, rangeSize.Height);
                            printedRanges.Add(range);
                        }
                        else
                        {
                            // Draw only if this cell is not already drawn on current page
                            if (!printedRanges.ContainsCell(pos))
                            {
                                // Calculate offset
                                float sX = curX;
                                for (int i = pos.Column - 1; i >= range.Start.Column; i--)
                                {
                                    float cw = this.GetColumnWidth(e.Graphics, i);
                                    sX -= cw;
                                }
                                float sY = curY;
                                for (int i = pos.Row - 1; i >= range.Start.Row; i--)
                                {
                                    float cw = this.GetRowHeight(e.Graphics, i);
                                    sY -= cw;
                                }
                                cellRectangle = new RectangleF(sX, sY, rangeSize.Width, rangeSize.Height);
                                printedRanges.Add(range);
                            }
                            else
                            {
                                cellRectangle = RectangleF.Empty;
                            }
                        }
                    }
                    else
                    {
                        cellRectangle = new RectangleF(curX, curY, colWidth, rowHeight);
                    }

                    if (!cellRectangle.IsEmpty)
                    {
                        SourceGrid.Cells.ICellVirtual cell = this.m_Grid.GetCell(pos);
                        if (cell != null)
                        {
                            CellContext ctx  = new CellContext(m_Grid, pos, cell);
                            RectangleF  clip = new RectangleF(Math.Max(cellRectangle.Left, area.Left),
                                                              Math.Max(cellRectangle.Top, area.Top),
                                                              Math.Min(cellRectangle.Right, area.Left + pageColumnWidth) - Math.Max(cellRectangle.Left, area.Left),
                                                              Math.Min(cellRectangle.Bottom, area.Bottom) - Math.Max(cellRectangle.Top, area.Top));
                            Region prevClip = e.Graphics.Clip;
                            try
                            {
                                e.Graphics.Clip = new Region(clip);
                                this.DrawCell(e.Graphics, ctx, cellRectangle);
                            }
                            finally
                            {
                                // Restore clip region
                                e.Graphics.Clip = prevClip;
                            }
                            // Check if left border can be drawn in current page
                            if (!ContainsInRange(rowHasLeftBorder, range.Start.Row, range.End.Row) &&
                                cellRectangle.Left >= area.Left)
                            {
                                e.Graphics.DrawLine(m_BorderPen, cellRectangle.Left, clip.Top, cellRectangle.Left, clip.Bottom);
                                AddRange(rowHasLeftBorder, range.Start.Row, range.End.Row);
                            }
                            // Check if top border can be drawn in current page
                            if (!ContainsInRange(columnHasTopBorder, range.Start.Column, range.End.Column) &&
                                cellRectangle.Top >= area.Top)
                            {
                                e.Graphics.DrawLine(m_BorderPen, clip.Left, cellRectangle.Top, clip.Right, cellRectangle.Top);
                                AddRange(columnHasTopBorder, range.Start.Column, range.End.Column);
                            }
                            // Check if right border can be drawn in current page
                            if (cellRectangle.Right <= area.Right)
                            {
                                e.Graphics.DrawLine(m_BorderPen, cellRectangle.Right, clip.Top, cellRectangle.Right, clip.Bottom);
                            }
                            // Check if bottom border can be drawn in current page
                            if (cellRectangle.Bottom <= area.Bottom)
                            {
                                e.Graphics.DrawLine(m_BorderPen, clip.Left, cellRectangle.Bottom, clip.Right, cellRectangle.Bottom);
                            }
                        }
                    }
                    // Set next column position
                    curX += colWidth;
                    m_NextColumnToPrint++;
                }
                // Set next row Y position
                curY += rowHeight;
                m_NextRowToPrint++;
                m_NextColumnToPrint = pageFirstColumn;
            }
            // If we have not reached last column, we will continue on next page
            if (pageLastColumn != RangeToPrint.End.Column)
            {
                m_NextRowToPrint    = pageFirstRow;
                m_NextColumnToPrint = pageLastColumn + 1;
            }
            else
            {
                m_NextColumnToPrint = RangeToPrint.Start.Column;
            }

            this.DrawFooter(e.Graphics, new RectangleF(e.MarginBounds.Left, e.MarginBounds.Bottom - m_FooterHeight, e.MarginBounds.Width, m_FooterHeight),
                            m_PageNo, m_PageCount);

            // If we have not reached last row we will continue on next page
            e.HasMorePages = (m_NextRowToPrint <= RangeToPrint.End.Row);
            // If there are no more pages, release resources
            if (e.HasMorePages)
            {
                m_PageNo++;
            }
        }
예제 #2
0
        public virtual void Export(GridVirtual grid, System.Drawing.Graphics graphics,
                                   GridRange rangeToExport, System.Drawing.Point destinationLocation)
        {
            if (rangeToExport.IsEmpty())
            {
                return;
            }

            System.Drawing.Point cellPoint = destinationLocation;

            using (DevAge.Drawing.GraphicsCache graphicsCache = new DevAge.Drawing.GraphicsCache(graphics))
            {
                for (int r = rangeToExport.Start.Row; r <= rangeToExport.End.Row; r++)
                {
                    int rowHeight = grid.Rows.GetHeight(r);

                    for (int c = rangeToExport.Start.Column; c <= rangeToExport.End.Column; c++)
                    {
                        Rectangle cellRectangle;
                        Position  pos = new Position(r, c);

                        Size cellSize = new Size(grid.Columns.GetWidth(c), rowHeight);

                        GridRange range = grid.PositionToCellRange(pos);

                        //support for RowSpan or ColSpan
                        //Note: for now I draw only the merged cell at the first position
                        // (this can cause a problem if you export partial range that contains a partial merged cells)
                        if (range.ColumnsCount > 1 || range.RowsCount > 1)
                        {
                            //Is the first position
                            if (range.Start == pos)
                            {
                                Size rangeSize = grid.RangeToSize(range);

                                cellRectangle = new Rectangle(cellPoint,
                                                              rangeSize);
                            }
                            else
                            {
                                cellRectangle = Rectangle.Empty;
                            }
                        }
                        else
                        {
                            cellRectangle = new Rectangle(cellPoint, cellSize);
                        }

                        if (cellRectangle.IsEmpty == false)
                        {
                            Cells.ICellVirtual cell    = grid.GetCell(pos);
                            CellContext        context = new CellContext(grid, pos, cell);
                            ExportCell(context, graphicsCache, cellRectangle);
                        }

                        cellPoint = new Point(cellPoint.X + cellSize.Width, cellPoint.Y);
                    }

                    cellPoint = new Point(destinationLocation.X, cellPoint.Y + rowHeight);
                }
            }
        }