C# GridView指定頁打印

指定頁打印很煩人,在網上找了很久沒找到合適的。終於耐下心自己寫了。:)

這個類有個缺陷:如果紙設的比較窄需要把一頁打在兩頁上會有點問題。

好了不多說了:源碼送上

//公用打印類

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Data;
using System.Windows.Forms;


namespace FrameWork.WinForm
{
    public class GridPrinter
    {
        // the grid to print
        private DataGridView dataGridView;

        // the PrintDocument
        private PrintDocument printDocument;

        // center printout?
        private bool centerOnPage;

        // has a title?
        private bool hasTitle;

        // title
        private string title;

        // font
        private Font titleFont;

        // title color
        private Color titleColor;

        // use paging?
        private bool paging;

        // row printing
        public static int currentRow;
        public static int TotalRows;

        // page printing
        public static int pageNumber;

        // page width
        public int pageWidth;

        // page height
        public int pageHeight;

        // left margin
        private int leftMargin;

        // top margin
        private int topMargin;

        // right margin
        private int rightMargin;

        // bottom margin
        private int bottomMargin;

        // y location placeholder
        private float currentY;

        // grid sizes
        private float rowHeaderHeight;
        private List<float> rowsHeight;
        private List<float> columnsWidth;
        private float dataGridViewWidth;

        // column stop points
        private List<int[]> mColumnPoints;
        private List<float> mColumnPointsWidth;
        private int mColumnPoint;

        public GridPrinter(DataGridView objDataGridView, PrintDocument objPrintDocument, bool bCenterOnPage, bool bHasTitle, string sTitle, Font objTitleFont, Color objTitleColor, bool bPaging)
        {
            dataGridView = objDataGridView;
            TotalRows = dataGridView.Rows.Count;

            printDocument = objPrintDocument;
            centerOnPage = bCenterOnPage;
            hasTitle = bHasTitle;
            title = sTitle;
            titleFont = objTitleFont;
            titleColor = objTitleColor;
            paging = bPaging;

            pageNumber = 0;

            rowsHeight = new List<float>();
            columnsWidth = new List<float>();

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

            if (!printDocument.DefaultPageSettings.Landscape)
            {
                pageWidth = printDocument.DefaultPageSettings.PaperSize.Width;
                pageHeight = printDocument.DefaultPageSettings.PaperSize.Height;
            }
            else
            {
                pageHeight = printDocument.DefaultPageSettings.PaperSize.Width;
                pageWidth = printDocument.DefaultPageSettings.PaperSize.Height;
            }

            leftMargin = printDocument.DefaultPageSettings.Margins.Left;
            topMargin = printDocument.DefaultPageSettings.Margins.Top;
            rightMargin = printDocument.DefaultPageSettings.Margins.Right;
            bottomMargin = printDocument.DefaultPageSettings.Margins.Bottom;

            currentRow = 0;
        }

        float HeaderHeight = 0;
        // calculate printing metrics
        private void Calculate(Graphics g)
        {
            if (pageNumber == 0)
            {
                SizeF tmpSize = new SizeF();
                Font tmpFont;
                float tmpWidth;

                dataGridViewWidth = 0;
                for (int i = 0; i < dataGridView.Columns.Count; i++)
                {
                    tmpFont = dataGridView.ColumnHeadersDefaultCellStyle.Font;
                    if (tmpFont == null)
                        tmpFont = dataGridView.DefaultCellStyle.Font;

                    tmpSize = g.MeasureString(dataGridView.Columns[i].HeaderText, tmpFont);
                    tmpWidth = tmpSize.Width;
                    rowHeaderHeight = tmpSize.Height + 10;

                    for (int j = 0; j < dataGridView.Rows.Count; j++)
                    {
                        tmpFont = dataGridView.Rows[j].DefaultCellStyle.Font;
                        if (tmpFont == null)
                            tmpFont = dataGridView.DefaultCellStyle.Font;

                        tmpSize = g.MeasureString("Anything", tmpFont);
                        rowsHeight.Add(tmpSize.Height + 5);

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

                int k;

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

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

                float mTempWidth = dataGridViewWidth;
                float mTempPrintArea = (float)pageWidth - (float)leftMargin - (float)rightMargin;

                if (dataGridViewWidth > mTempPrintArea)
                {
                    mTempWidth = 0.0F;
                    for (k = 0; k < dataGridView.Columns.Count; k++)
                    {
                        if (dataGridView.Columns[k].Visible)
                        {
                            mTempWidth += columnsWidth[k];
                            if (mTempWidth > mTempPrintArea)
                            {
                                mTempWidth -= columnsWidth[k];
                                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
                                mColumnPointsWidth.Add(mTempWidth);
                                mStartPoint = k;
                                mTempWidth = columnsWidth[k];
                            }
                        }
                        mEndPoint = k + 1;
                    }
                }

                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
                mColumnPointsWidth.Add(mTempWidth);
                mColumnPoint = 0;
            }

            HeaderHeight = (float)topMargin + rowHeaderHeight;
            HeaderHeight += g.MeasureString("第", PageStringFont).Height;
            HeaderHeight += g.MeasureString(title, titleFont).Height;
        }

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

        // header printing
        private void DrawHeader(Graphics g,float totalPages)
        {
            currentY = (float)topMargin;

            if (paging)
            {
                pageNumber++;
                string PageString = string.Format("第{0}/{1}頁", pageNumber, Convert.ToInt32( totalPages));

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

                RectangleF PageStringRectangle = new RectangleF((float)leftMargin, currentY, (float)pageWidth - (float)rightMargin - (float)leftMargin, g.MeasureString(PageString, PageStringFont).Height);

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

                currentY += g.MeasureString(PageString, PageStringFont).Height;
            }

            if (hasTitle)
            {
                StringFormat TitleFormat = new StringFormat();
                TitleFormat.Trimming = StringTrimming.Word;
                TitleFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                if (centerOnPage)
                    TitleFormat.Alignment = StringAlignment.Center;
                else
                    TitleFormat.Alignment = StringAlignment.Near;

                RectangleF TitleRectangle = new RectangleF((float)leftMargin, currentY, (float)pageWidth - (float)rightMargin - (float)leftMargin, g.MeasureString(title, titleFont).Height);

                g.DrawString(title, titleFont, new SolidBrush(titleColor), TitleRectangle, TitleFormat);

                currentY += g.MeasureString(title, titleFont).Height;
            }

            float CurrentX = (float)leftMargin;
            if (centerOnPage)
                CurrentX += (((float)pageWidth - (float)rightMargin - (float)leftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;

            Color HeaderForeColor = dataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
            if (HeaderForeColor.IsEmpty)
                HeaderForeColor = dataGridView.DefaultCellStyle.ForeColor;
            SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor);

            Color HeaderBackColor = dataGridView.ColumnHeadersDefaultCellStyle.BackColor;
            if (HeaderBackColor.IsEmpty)
                HeaderBackColor = dataGridView.DefaultCellStyle.BackColor;
            SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor);

            Pen TheLinePen = new Pen(dataGridView.GridColor, 1);

            Font HeaderFont = dataGridView.ColumnHeadersDefaultCellStyle.Font;
            if (HeaderFont == null)
                HeaderFont = dataGridView.DefaultCellStyle.Font;

            RectangleF HeaderBounds = new RectangleF(CurrentX, currentY, mColumnPointsWidth[mColumnPoint], rowHeaderHeight);
            g.FillRectangle(HeaderBackBrush, HeaderBounds);

            StringFormat CellFormat = new StringFormat();
            CellFormat.Trimming = StringTrimming.Word;
            CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;

            RectangleF CellBounds;
            float ColumnWidth;
            for (int i = (int)mColumnPoints[mColumnPoint].GetValue(0); i < (int)mColumnPoints[mColumnPoint].GetValue(1); i++)
            {
                if (!dataGridView.Columns[i].Visible) continue;

                ColumnWidth = columnsWidth[i];

                if (dataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right"))
                    CellFormat.Alignment = StringAlignment.Far;
                else if (dataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center"))
                    CellFormat.Alignment = StringAlignment.Center;
                else
                    CellFormat.Alignment = StringAlignment.Near;
                CellFormat.LineAlignment = StringAlignment.Center;
                CellBounds = new RectangleF(CurrentX, currentY, ColumnWidth, rowHeaderHeight);

                g.DrawString(dataGridView.Columns[i].HeaderText, HeaderFont, HeaderForeBrush, CellBounds, CellFormat);

                if (dataGridView.RowHeadersBorderStyle != DataGridViewHeaderBorderStyle.None)
                    g.DrawRectangle(TheLinePen, CurrentX, currentY, ColumnWidth, rowHeaderHeight);

                CurrentX += ColumnWidth;
            }

            currentY += rowHeaderHeight;
        }


        // common row printing function
        private bool DrawRows(Graphics g)
        {
            Pen TheLinePen = new Pen(dataGridView.GridColor, 1);

            Font RowFont;
            Color RowForeColor;
            Color RowBackColor;
            SolidBrush RowForeBrush;
            SolidBrush RowBackBrush;
            SolidBrush RowAlternatingBackBrush;

            StringFormat CellFormat = new StringFormat();
            CellFormat.Trimming = StringTrimming.Word;
            CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;

            RectangleF RowBounds;
            float CurrentX;
            float ColumnWidth;
            while (currentRow < dataGridView.Rows.Count)
            {
                if (dataGridView.Rows[currentRow].Visible)
                {
                    RowFont = dataGridView.Rows[currentRow].DefaultCellStyle.Font;
                    if (RowFont == null)
                        RowFont = dataGridView.DefaultCellStyle.Font;

                    //RowForeColor = dataGridView.Rows[currentRow].DefaultCellStyle.ForeColor;
                    RowForeColor = Color.Black;
                    if (RowForeColor.IsEmpty)
                        RowForeColor = dataGridView.DefaultCellStyle.ForeColor;
                    RowForeBrush = new SolidBrush(RowForeColor);

                    //RowBackColor = dataGridView.Rows[currentRow].DefaultCellStyle.BackColor;
                    RowBackColor = Color.White;
                    if (RowBackColor.IsEmpty)
                    {
                        RowBackBrush = new SolidBrush(dataGridView.DefaultCellStyle.BackColor);
                        RowAlternatingBackBrush = new SolidBrush(dataGridView.AlternatingRowsDefaultCellStyle.BackColor);
                    }
                    else
                    {
                        RowBackBrush = new SolidBrush(RowBackColor);
                        RowAlternatingBackBrush = new SolidBrush(RowBackColor);
                    }

                    CurrentX = (float)leftMargin;
                    if (centerOnPage)
                        CurrentX += (((float)pageWidth - (float)rightMargin - (float)leftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;

                    RowBounds = new RectangleF(CurrentX, currentY, mColumnPointsWidth[mColumnPoint], rowsHeight[currentRow]);

                    if (currentRow % 2 == 0)
                        g.FillRectangle(RowBackBrush, RowBounds);
                    else
                        g.FillRectangle(RowAlternatingBackBrush, RowBounds);

                    for (int CurrentCell = (int)mColumnPoints[mColumnPoint].GetValue(0); CurrentCell < (int)mColumnPoints[mColumnPoint].GetValue(1); CurrentCell++)
                    {
                        if (!dataGridView.Columns[CurrentCell].Visible) continue;

                        if (dataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Right"))
                            CellFormat.Alignment = StringAlignment.Far;
                        else if (dataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Center"))
                            CellFormat.Alignment = StringAlignment.Center;
                        else
                            CellFormat.Alignment = StringAlignment.Near;
                        CellFormat.LineAlignment = StringAlignment.Center;
                        ColumnWidth = columnsWidth[CurrentCell];
                        RectangleF CellBounds = new RectangleF(CurrentX, currentY, ColumnWidth, rowsHeight[currentRow]);

                        g.DrawString(dataGridView.Rows[currentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat);

                        if (dataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None)
                            g.DrawRectangle(TheLinePen, CurrentX, currentY, ColumnWidth, rowsHeight[currentRow]);

                        CurrentX += ColumnWidth;
                    }
                    currentY += rowsHeight[currentRow];

                    if ((int)currentY > (pageHeight - topMargin - bottomMargin))
                    {
                        currentRow++;
                        return true;
                    }
                }
                currentRow++;
            }

            currentRow = 0;
            mColumnPoint++;

            if (mColumnPoint == mColumnPoints.Count)
            {
                mColumnPoint = 0;
                return false;
            }
            else
                return true;
        }

        public bool DrawDataGridView(Graphics g, int start, int end)
        {
            try
            {
                Calculate(g);

                if (pageNumber < start - 1)
                    pageNumber = start - 1;

                float rh = rowsHeight[currentRow];

                float h = (pageHeight - topMargin - bottomMargin) - HeaderHeight;
                int pagerows = Convert.ToInt32(h / rh);
                float totalPages = dataGridView.Rows.Count/(float)pagerows;

                if ((int)totalPages <totalPages)
                    totalPages = (int)totalPages +1;


                currentRow = pageNumber * pagerows;

                DrawHeader(g,totalPages);

                bool hasPages = DrawRows(g);

                if (pageNumber >= end)
                    return false;
                else
                    return hasPages;
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR: " + ex.Message.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        // the main grid printing method
        public bool DrawDataGridView(Graphics g )
        {
            try
            {
                Calculate(g);

                float rh = rowsHeight[currentRow];

                float h = (pageHeight - topMargin - bottomMargin) - HeaderHeight;
                int pagerows = Convert.ToInt32(h / rh);
                float totalPages = rowsHeight.Count / (float)pagerows;

                if ((int)totalPages < totalPages)
                    totalPages = (int)totalPages + 1;

                DrawHeader(g,totalPages);
                bool bContinue = DrawRows(g);
                return bContinue;
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR: " + ex.Message.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
    }

}

 

調用方法:

public partial class winFind : Form
    {
        GridPrinter gridPrinter;

    ....

        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (InitializePrinting())
            {
                PrintController pc = new StandardPrintController();
                printDocument1.PrintController = pc;

                //printDocument1.Print();

                PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
                printPreviewDialog.Document = printDocument1;

                printPreviewDialog.ShowDialog();
            }
           
        }

 

        private bool InitializePrinting()
        {
            PrintDialog printDialog = new PrintDialog();
            printDialog.AllowSomePages = true;
            printDialog.ShowHelp = true;

            if (printDialog.ShowDialog() != DialogResult.OK)
                return false;
           
            printDocument1.DocumentName = "打印標題";
            printDocument1.PrinterSettings = printDialog.PrinterSettings;
            printDocument1.DefaultPageSettings.PrinterSettings.PrintRange = printDialog.PrinterSettings.DefaultPageSettings.PrinterSettings.PrintRange;
            printDocument1.DefaultPageSettings.Margins = new Margins(20, 20, 20, 20);

            gridPrinter = new GridPrinter(dvgList, printDocument1, true, true, "打印標題", new Font("黑體", 18, FontStyle.Bold, GraphicsUnit.Point), Color.Black, true);
            return true;
        }

 

        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            try
            {
                if (e.PageSettings.PrinterSettings.PrintRange == PrintRange.SomePages )
                {
                    if (e.PageSettings.PrinterSettings.FromPage >0)
                        e.HasMorePages = gridPrinter.DrawDataGridView(e.Graphics, e.PageSettings.PrinterSettings.FromPage, e.PageSettings.PrinterSettings.ToPage);
                }
                else
                {
                    e.HasMorePages = gridPrinter.DrawDataGridView(e.Graphics);
                }
            }
            catch (Exception ex)
            {
                Error2Log.To2LogFile(ex,"打印出錯");
                MessageBox.Show("請檢查打印機是否安裝正確!", "不能連接打印機", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

}

 

轉自:http://www.cnblogs.com/uu08/archive/2009/10/23/1588853.html

發佈了14 篇原創文章 · 獲贊 12 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章