DataGridView打印类

 public class DataGridViewPrinter
    {
        // The DataGridView Control which will be printed
        private DataGridView TheDataGridView;
        // The PrintDocument to be used for printing
        private PrintDocument ThePrintDocument;
        // Determine if the report will be
        // printed in the Top-Center of the page
        private bool IsCenterOnPage;
        // Determine if the page contain title text
        private bool IsWithTitle;
        // The title text to be printed
        // in each page (if IsWithTitle is set to true)
        private string TheTitleText;
        // The font to be used with the title
        // text (if IsWithTitle is set to true)
        private Font TheTitleFont;
        // The color to be used with the title
        // text (if IsWithTitle is set to true)
        private Color TheTitleColor;
        // Determine if paging is used
        private bool IsWithPaging;

        // A static parameter that keep track
        // on which Row (in the DataGridView control)
        // that should be printed
        static int CurrentRow;

        static int PageNumber;

        private int PageWidth;
        private int PageHeight;
        private int LeftMargin;
        private int TopMargin;
        private int RightMargin;
        private int BottomMargin;

        // A parameter that keep track
        // on the y coordinate of the page,
        // so the next object to be printed
        // will start from this y coordinate
        private float CurrentY;

        private float RowHeaderHeight;
        private List<float> RowsHeight;
        private List<float> ColumnsWidth;
        private float TheDataGridViewWidth;

        // Maintain a generic list to hold start/stop
        // points for the column printing
        // This will be used for wrapping
        // in situations where the DataGridView will not
        // fit on a single page
        private List<int[]> mColumnPoints;
        private List<float> mColumnPointsWidth;
        private int mColumnPoint;

        public DataGridViewPrinter(DataGridView dgv, bool withTitle, string titleText, string aTitleText, Font aTitleFont, Color aTitleColor, bool WithPaging)
        {
            TheDataGridView = dgv;
            ThePrintDocument = new PrintDocument();
        }
        // The class constructor
        public DataGridViewPrinter(DataGridView aDataGridView,
            PrintDocument aPrintDocument,
            bool CenterOnPage, bool WithTitle,
            string aTitleText, Font aTitleFont,
            Color aTitleColor, bool WithPaging)
        {
            TheDataGridView = aDataGridView;
            ThePrintDocument = aPrintDocument;
            IsCenterOnPage = CenterOnPage;
            IsWithTitle = WithTitle;
            TheTitleText = aTitleText;
            TheTitleFont = aTitleFont;
            TheTitleColor = aTitleColor;
            IsWithPaging = WithPaging;

            PageNumber = 0;

            RowsHeight = new List<float>();
            ColumnsWidth = new List<float>();

            mColumnPoints = new List<int[]>();
            mColumnPointsWidth = new List<float>();

            // Claculating the PageWidth and the PageHeight
            if (!ThePrintDocument.DefaultPageSettings.Landscape)
            {
                PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Width;
                PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Height;
            }
            else
            {
                PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Width;
                PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Height;
            }

            // Claculating the page margins
            LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left;
            TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top;
            RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right;
            BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom;

            // First, the current row to be printed
            // is the first row in the DataGridView control
            CurrentRow = 0;
        }

        // The function that calculate
        // the height of each row (including the header row),
        // the width of each column (according
        // to the longest text in all its cells including
        // the header cell), and the whole DataGridView width
        private void Calculate(Graphics g)
        {
            if (PageNumber == 0)
            // Just calculate once
            {
                SizeF tmpSize = new SizeF();
                Font tmpFont;
                float tmpWidth;

                TheDataGridViewWidth = 0;
                for (int i = 0; i < TheDataGridView.Columns.Count; i++)
                {
                    tmpFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
                    if (tmpFont == null)
                        // If there is no special HeaderFont style,
                        // then use the default DataGridView font style
                        tmpFont = TheDataGridView.DefaultCellStyle.Font;

                    tmpSize = g.MeasureString(
                              TheDataGridView.Columns[i].HeaderText,
                              tmpFont);
                    tmpWidth = tmpSize.Width;
                    RowHeaderHeight = tmpSize.Height;

                    for (int j = 0; j < TheDataGridView.Rows.Count; j++)
                    {
                        tmpFont = TheDataGridView.Rows[j].DefaultCellStyle.Font;
                        if (tmpFont == null)
                            // If the there is no special font style of the
                            // CurrentRow, then use the default one associated
                            // with the DataGridView control
                            tmpFont = TheDataGridView.DefaultCellStyle.Font;

                        tmpSize = g.MeasureString("Anything", tmpFont);
                        RowsHeight.Add(tmpSize.Height);

                        tmpSize = g.MeasureString(TheDataGridView.Rows[j].Cells[i].EditedFormattedValue.ToString(), tmpFont);
                        if (tmpSize.Width > tmpWidth)
                            tmpWidth = tmpSize.Width;
                    }
                    if (TheDataGridView.Columns[i].Visible)
                        TheDataGridViewWidth += tmpWidth;
                    ColumnsWidth.Add(tmpWidth);
                }

                // Define the start/stop column points
                // based on the page width and
                // the DataGridView Width
                // We will use this to determine
                // the columns which are drawn on each page
                // and how wrapping will be handled
                // By default, the wrapping will occurr
                // such that the maximum number of
                // columns for a page will be determine
                int k;

                int mStartPoint = 0;
                for (k = 0; k < TheDataGridView.Columns.Count; k++)
                    if (TheDataGridView.Columns[k].Visible)
                    {
                        mStartPoint = k;
                        break;
                    }

                int mEndPoint = TheDataGridView.Columns.Count;
                for (k = TheDataGridView.Columns.Count - 1; k >= 0; k--)
                    if (TheDataGridView.Columns[k].Visible)
                    {
                        mEndPoint = k + 1;
                        break;
                    }

                float mTempWidth = TheDataGridViewWidth;
                float mTempPrintArea = (float)PageWidth - (float)LeftMargin -
                    (float)RightMargin;

                // We only care about handling
                // where the total datagridview width is bigger
                // then the print area
                if (TheDataGridViewWidth > mTempPrintArea)
                {
                    mTempWidth = 0.0F;
                    for (k = 0; k < TheDataGridView.Columns.Count; k++)
                    {
                        if (TheDataGridView.Columns[k].Visible)
                        {
                            mTempWidth += ColumnsWidth[k];
                            // If the width is bigger
                            // than the page area, then define a new
                            // column print range
                            if (mTempWidth > mTempPrintArea)
                            {
                                mTempWidth -= ColumnsWidth[k];
                                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
                                mColumnPointsWidth.Add(mTempWidth);
                                mStartPoint = k;
                                mTempWidth = ColumnsWidth[k];
                            }
                        }
                        // Our end point is actually
                        // one index above the current index
                        mEndPoint = k + 1;
                    }
                }
                // Add the last set of columns
                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
                mColumnPointsWidth.Add(mTempWidth);
                mColumnPoint = 0;
            }
        }

        // The funtion that print the title, page number, and the header row
        private void DrawHeader(Graphics g)
        {
            CurrentY = (float)TopMargin;

            // Printing the page number (if isWithPaging is set to true)

            if (IsWithPaging)
            {
                PageNumber++;
                string PageString = "第" + PageNumber.ToString()+"页";

                StringFormat PageStringFormat = new StringFormat();
                PageStringFormat.Trimming = StringTrimming.Word;
                PageStringFormat.FormatFlags = StringFormatFlags.NoWrap |
                    StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                PageStringFormat.Alignment = StringAlignment.Far;

                Font PageStringFont = new Font("Tahoma", 8, FontStyle.Regular,
                    GraphicsUnit.Point);

                RectangleF PageStringRectangle =
                   new RectangleF((float)LeftMargin, CurrentY,
                   (float)PageWidth - (float)RightMargin - (float)LeftMargin-  g.MeasureString(PageString, PageStringFont).Width,
                   g.MeasureString(PageString, PageStringFont).Height);

                g.DrawString(PageString, PageStringFont,
                   new SolidBrush(Color.Black),
                   PageStringRectangle, PageStringFormat);

                CurrentY += g.MeasureString(PageString,
                                     PageStringFont).Height;
            }
            else PageNumber++;

            // Printing the title (if IsWithTitle is set to true)
            if (IsWithTitle)
            {
                StringFormat TitleFormat = new StringFormat();
                TitleFormat.Trimming = StringTrimming.Word;
                TitleFormat.FormatFlags = StringFormatFlags.NoWrap |
                    StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                if (IsCenterOnPage)
                    TitleFormat.Alignment = StringAlignment.Center;
                else
                    TitleFormat.Alignment = StringAlignment.Near;

                RectangleF TitleRectangle =
                    new RectangleF((float)LeftMargin, CurrentY,
                    (float)PageWidth - (float)RightMargin - (float)LeftMargin,
                    g.MeasureString(TheTitleText, TheTitleFont).Height);

                g.DrawString(TheTitleText, TheTitleFont,
                    new SolidBrush(TheTitleColor),
                    TitleRectangle, TitleFormat);

                CurrentY += g.MeasureString(TheTitleText, TheTitleFont).Height;
            }

            // Calculating the starting x coordinate
            // that the printing process will start from
            float CurrentX = (float)LeftMargin;
            if (IsCenterOnPage)
                CurrentX += (((float)PageWidth - (float)RightMargin -
                  (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;

            // Setting the HeaderFore style
            Color HeaderForeColor =
                  TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
            if (HeaderForeColor.IsEmpty)
                // If there is no special HeaderFore style,
                // then use the default DataGridView style
                HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
            SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor);

            // Setting the HeaderBack style
            Color HeaderBackColor =
                  TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor;
            if (HeaderBackColor.IsEmpty)
                // If there is no special HeaderBack style,
                // then use the default DataGridView style
                HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor;
            SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor);

            // Setting the LinePen that will
            // be used to draw lines and rectangles
            // (derived from the GridColor property
            // of the DataGridView control)
            Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);

            // Setting the HeaderFont style
            Font HeaderFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
            if (HeaderFont == null)
                // If there is no special HeaderFont style,
                // then use the default DataGridView font style
                HeaderFont = TheDataGridView.DefaultCellStyle.Font;

            // Calculating and drawing the HeaderBounds       
            RectangleF HeaderBounds = new RectangleF(CurrentX, CurrentY,
                mColumnPointsWidth[mColumnPoint], RowHeaderHeight);
            g.FillRectangle(HeaderBackBrush, HeaderBounds);

            // Setting the format that will be
            // used to print each cell of the header row
            StringFormat CellFormat = new StringFormat();
            CellFormat.Trimming = StringTrimming.Word;
            CellFormat.FormatFlags = StringFormatFlags.NoWrap |
               StringFormatFlags.LineLimit | StringFormatFlags.NoClip;

            // Printing each visible cell of the header row
            RectangleF CellBounds;
            float ColumnWidth;
            for (int i = (int)mColumnPoints[mColumnPoint].GetValue(0);
                i < (int)mColumnPoints[mColumnPoint].GetValue(1); i++)
            {
                // If the column is not visible then ignore this iteration
                if (!TheDataGridView.Columns[i].Visible) continue;

                ColumnWidth = ColumnsWidth[i];

                // Check the CurrentCell alignment
                // and apply it to the CellFormat
                if (TheDataGridView.ColumnHeadersDefaultCellStyle.
                           Alignment.ToString().Contains("Right"))
                    CellFormat.Alignment = StringAlignment.Far;
                else if (TheDataGridView.ColumnHeadersDefaultCellStyle.
                         Alignment.ToString().Contains("Center"))
                    CellFormat.Alignment = StringAlignment.Center;
                else
                    CellFormat.Alignment = StringAlignment.Near;

                CellBounds = new RectangleF(CurrentX, CurrentY,
                             ColumnWidth, RowHeaderHeight);

                // Printing the cell text
                g.DrawString(TheDataGridView.Columns[i].HeaderText,
                             HeaderFont, HeaderForeBrush,
                   CellBounds, CellFormat);

                // Drawing the cell bounds
                // Draw the cell border only if the HeaderBorderStyle is not None
                if (TheDataGridView.RowHeadersBorderStyle !=
                                DataGridViewHeaderBorderStyle.None)
                    g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth,
                        RowHeaderHeight);

                CurrentX += ColumnWidth;
            }

            CurrentY += RowHeaderHeight;
        }

        // The function that print a bunch of rows that fit in one page
        // When it returns true, meaning that
        // there are more rows still not printed,
        // so another PagePrint action is required
        // When it returns false, meaning that all rows are printed
        // (the CureentRow parameter reaches
        // the last row of the DataGridView control)
        // and no further PagePrint action is required
        private bool DrawRows(Graphics g)
        {
            // Setting the LinePen that will be used to draw lines and rectangles
            // (derived from the GridColor property of the DataGridView control)
            Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);

            // The style paramters that will be used to print each cell
            Font RowFont;
            Color RowForeColor;
            Color RowBackColor;
            SolidBrush RowForeBrush;
            SolidBrush RowBackBrush;
            SolidBrush RowAlternatingBackBrush;

            // Setting the format that will be used to print each cell
            StringFormat CellFormat = new StringFormat();
            CellFormat.Trimming = StringTrimming.Word;
            CellFormat.FormatFlags = StringFormatFlags.NoWrap |
                                     StringFormatFlags.LineLimit;

            // Printing each visible cell
            RectangleF RowBounds;
            float CurrentX;
            float ColumnWidth;
            while (CurrentRow < TheDataGridView.Rows.Count)
            {
                // Print the cells of the CurrentRow only if that row is visible
                if (TheDataGridView.Rows[CurrentRow].Visible)
                {
                    // Setting the row font style
                    RowFont = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font;
                    // If the there is no special font style of the CurrentRow,
                    // then use the default one associated with the DataGridView control
                    if (RowFont == null)
                        RowFont = TheDataGridView.DefaultCellStyle.Font;

                    // Setting the RowFore style
                    RowForeColor =
                      TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor;
                    // If the there is no special RowFore style of the CurrentRow,
                    // then use the default one associated with the DataGridView control
                    if (RowForeColor.IsEmpty)
                        RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
                    RowForeBrush = new SolidBrush(RowForeColor);

                    // Setting the RowBack (for even rows) and the RowAlternatingBack
                    // (for odd rows) styles
                    RowBackColor =
                      TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor;
                    // If the there is no special RowBack style of the CurrentRow,
                    // then use the default one associated with the DataGridView control
                    if (RowBackColor.IsEmpty)
                    {
                        RowBackBrush = new SolidBrush(
                              TheDataGridView.DefaultCellStyle.BackColor);
                        RowAlternatingBackBrush = new
                            SolidBrush(
                            TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor);
                    }
                    // If the there is a special RowBack style of the CurrentRow,
                    // then use it for both the RowBack and the RowAlternatingBack styles
                    else
                    {
                        RowBackBrush = new SolidBrush(RowBackColor);
                        RowAlternatingBackBrush = new SolidBrush(RowBackColor);
                    }

                    // Calculating the starting x coordinate
                    // that the printing process will
                    // start from
                    CurrentX = (float)LeftMargin;
                    if (IsCenterOnPage)
                        CurrentX += (((float)PageWidth - (float)RightMargin -
                            (float)LeftMargin) -
                            mColumnPointsWidth[mColumnPoint]) / 2.0F;

                    // Calculating the entire CurrentRow bounds               
                    RowBounds = new RectangleF(CurrentX, CurrentY,
                        mColumnPointsWidth[mColumnPoint], RowsHeight[CurrentRow]);

                    // Filling the back of the CurrentRow
                    if (CurrentRow % 2 == 0)
                        g.FillRectangle(RowBackBrush, RowBounds);
                    else
                        g.FillRectangle(RowAlternatingBackBrush, RowBounds);

                    // Printing each visible cell of the CurrentRow               
                    for (int CurrentCell = (int)mColumnPoints[mColumnPoint].GetValue(0);
                        CurrentCell < (int)mColumnPoints[mColumnPoint].GetValue(1);
                        CurrentCell++)
                    {
                        // If the cell is belong to invisible
                        // column, then ignore this iteration
                        if (!TheDataGridView.Columns[CurrentCell].Visible) continue;

                        // Check the CurrentCell alignment
                        // and apply it to the CellFormat
                        if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.
                                Alignment.ToString().Contains("Right"))
                            CellFormat.Alignment = StringAlignment.Far;
                        else if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.
                                Alignment.ToString().Contains("Center"))
                            CellFormat.Alignment = StringAlignment.Center;
                        else
                            CellFormat.Alignment = StringAlignment.Near;

                        ColumnWidth = ColumnsWidth[CurrentCell];
                        RectangleF CellBounds = new RectangleF(CurrentX, CurrentY,
                            ColumnWidth, RowsHeight[CurrentRow]);

                        // Printing the cell text
                        g.DrawString(
                          TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].
                          EditedFormattedValue.ToString(), RowFont, RowForeBrush,
                          CellBounds, CellFormat);

                        // Drawing the cell bounds
                        // Draw the cell border only
                        // if the CellBorderStyle is not None
                        if (TheDataGridView.CellBorderStyle !=
                                    DataGridViewCellBorderStyle.None)
                            g.DrawRectangle(TheLinePen, CurrentX, CurrentY,
                                  ColumnWidth, RowsHeight[CurrentRow]);

                        CurrentX += ColumnWidth;
                    }
                    CurrentY += RowsHeight[CurrentRow];

                    // Checking if the CurrentY is exceeds the page boundries
                    // If so then exit the function and returning true meaning another
                    // PagePrint action is required
                    if ((int)CurrentY > (PageHeight - TopMargin - BottomMargin))
                    {
                        CurrentRow++;
                        return true;
                    }
                }
                CurrentRow++;
            }

            CurrentRow = 0;
            // Continue to print the next group of columns
            mColumnPoint++;

            if (mColumnPoint == mColumnPoints.Count)
            // Which means all columns are printed
            {
                mColumnPoint = 0;
                return false;
            }
            else
                return true;
        }

        // The method that calls all other functions
        public bool DrawDataGridView(Graphics g)
        {
            try
            {
                Calculate(g);
                DrawHeader(g);
                bool bContinue = DrawRows(g);
                return bContinue;
            }
            catch (Exception ex)
            {
                MessageBox.Show("操作失败: " + ex.Message.ToString(),
                    Application.ProductName + " - 错误", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                return false;
            }
        }
    }

 

 

调用

    public class DGVPrinter : IPrinter
    {
        PrintDocument MyPrintDocument;
        Basic.DataGridViewPrinter MyDataGridViewPrinter;
        DataGridView dataGridView1;

        public DGVPrinter(DataGridView dgv)
        {
            dataGridView1 = dgv;
            MyPrintDocument = new PrintDocument();
            MyPrintDocument.PrintPage += new PrintPageEventHandler(MyPrintDocument_PrintPage);
        }

        // The class that will do the printing process.

        public void print()
        {
            //Basic.Printer printer = new Basic.Printer(dataGridView1,dtpStartTime.Text+"至"+dtpEndTime.Text,"","","","","",false);
            //printer.Print();

            if (SetupThePrinting())
            {
                PrintPreviewDialog MyPrintPreviewDialog = new PrintPreviewDialog();
                MyPrintPreviewDialog.Document = MyPrintDocument;
                MyPrintPreviewDialog.ShowIcon = false;
                Form f = dataGridView1.FindForm();
                MyPrintPreviewDialog.WindowState = FormWindowState.Maximized;
                MyPrintPreviewDialog.ShowDialog();
            }
            // if (SetupThePrinting())
            //   MyPrintDocument.Print();

        }

        private void MyPrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            bool more = MyDataGridViewPrinter.DrawDataGridView(e.Graphics);
            if (more == true)
                e.HasMorePages = true;
        }
        // The Print Preview Button
        private void btnPrintPreview_Click(object sender, EventArgs e)
        {
            if (SetupThePrinting())
            {
                PrintPreviewDialog MyPrintPreviewDialog = new PrintPreviewDialog();
                MyPrintPreviewDialog.Document = MyPrintDocument;
                MyPrintPreviewDialog.ShowDialog();
            }
        }
        private bool SetupThePrinting()
        {

            PrintDialog MyPrintDialog = new PrintDialog();
            // MyPrintDialog.PrinterSettings = true;
            MyPrintDialog.AllowCurrentPage = false;
            MyPrintDialog.AllowPrintToFile = false;
            MyPrintDialog.AllowSelection = false;
            MyPrintDialog.AllowSomePages = false;
            MyPrintDialog.PrintToFile = false;
            MyPrintDialog.ShowHelp = false;
            MyPrintDialog.ShowNetwork = false;
            MyPrintDialog.Document = MyPrintDocument;
            MyPrintDialog.Document.DefaultPageSettings.Landscape = true;

            if (MyPrintDialog.ShowDialog() != DialogResult.OK)
                return false;
            //   MyPrintDocument = new PrintDocument();
            MyPrintDocument.DocumentName = "";
            MyPrintDocument.PrinterSettings = MyPrintDialog.PrinterSettings;
            MyPrintDocument.DefaultPageSettings = MyPrintDialog.PrinterSettings.DefaultPageSettings;
            MyPrintDocument.DefaultPageSettings.Margins = new Margins(40, 40, 40, 40);

            //if (MessageBox.Show("Do you want the report to be centered on the page",  "InvoiceManager - Center on Page", MessageBoxButtons.YesNo,    MessageBoxIcon.Question) == DialogResult.Yes)

            MyDataGridViewPrinter = new DataGridViewPrinter(dataGridView1, MyPrintDocument, true, true, "",
                new Font("Tahoma", 18, FontStyle.Bold, GraphicsUnit.Point), Color.Black, true);
            //else
            //    MyDataGridViewPrinter = new DataGridViewPrinter(dataGridView1,
            //    MyPrintDocument, false, true, "Customers", new Font("Tahoma", 18,
            //    FontStyle.Bold, GraphicsUnit.Point), Color.Black, true);

            return true;
        }
    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值