打印DataGridView數據,可以加眉頭和頁尾

 由於數據保密性故將圖片處理,代碼先貼上

 

 

獲取數據代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

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

namespace PrintStock
{
    public partial class PrintStockList : Form
    {
        public PrintStockList()
        {
            InitializeComponent();
        }

        DataGridViewPrinter MyDataGridViewPrinter;
        private string FootText;

        private void PrintStockList_Load(object sender, EventArgs e)
        {
            txtop_date.Text = DateTime.Now.ToString("yyyyMMdd");
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtstock_code.Text))
            {
                MessageBox.Show("請輸入股權代碼!", "錯誤提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            string stock_code = txtstock_code.Text;
            int op_date = 0;
            if (!string.IsNullOrEmpty(txtop_date.Text))
                op_date = Convert.ToInt32(txtop_date.Text);
            int begin_amount = 0;
            if (!string.IsNullOrEmpty(txtbegin_amount.Text))
                begin_amount = Convert.ToInt32(txtbegin_amount.Text);
            int end_amount = 0;
            if (!string.IsNullOrEmpty(txtend_amount.Text))
                end_amount = Convert.ToInt32(txtend_amount.Text);

            DataTable dtdt = TradeDAL.Stock.GetSQL_maStockCode(stock_code);
            if (dtdt != null)
            {

                DataTable dt1 = TradeDAL.Stock.GetSQL_reportStockAccount(stock_code);

                lblstock_account_amount.Text = dt1.Rows[0]["stock_account_amount"].ToString();

                lblstock_code.Text = dt1.Rows[0]["stock_code"].ToString();

                lblstock_name.Text = dt1.Rows[0]["stock_name"].ToString();

                lbltotal_amount.Text = dt1.Rows[0]["total_amount"].ToString();
                
                DataTable dt2 = TradeDAL.Stock.GetSQL_reportStockAccount(stock_code, op_date, begin_amount, end_amount);
               
                DataTable dt = new DataTable("stock_list");
                DataColumn column;
                DataRow row;

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "序號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權託管證編號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股東帳號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股東名稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "證件號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權類別";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "聯繫地址";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "郵編";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "電話";
                column.ReadOnly = true;
                dt.Columns.Add(column);






                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "資金帳號";
                column.ReadOnly = true;
                dt.Columns.Add(column);  

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權狀態";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股東簡稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權代碼";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權名稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股權類別編號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "存入數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "轉出數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "凍結數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "質押數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "可交易數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "當前數量";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "自然人類別";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "地區編號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "地區名稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股份權益類別";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "股份權益名稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "移動電話";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "摘要";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "銀行編號";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "銀行名稱";
                column.ReadOnly = true;
                dt.Columns.Add(column);

                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "銀行帳號";
                column.ReadOnly = true;
                dt.Columns.Add(column);


                for (int i = 0; i < dt2.Rows.Count; i++)
                {
                    row = dt.NewRow();
                    row["序號"] = (i + 1).ToString();
                    row["股權託管證編號"] = dt2.Rows[i]["trustee_id"].ToString();
                    row["股東帳號"] = dt2.Rows[i]["stock_account"].ToString();
                    row["股東名稱"] = dt2.Rows[i]["customer_name"].ToString();
                    row["證件號"] = dt2.Rows[i]["id"].ToString();
                    row["股權類別"] = dt2.Rows[i]["stock_bonus_type_name"].ToString();
                    row["股權數量"] = dt2.Rows[i]["begin_amount"].ToString();
                    row["聯繫地址"] = dt2.Rows[i]["address"].ToString();
                    row["郵編"] = dt2.Rows[i]["zip"].ToString();
                    row["電話"] = dt2.Rows[i]["phone"].ToString();

                    row["資金帳號"] = dt2.Rows[i]["customer_id"].ToString();
                    row["股權狀態"] = dt2.Rows[i]["stock_status"].ToString();
                    row["股東簡稱"] = dt2.Rows[i]["simple_name"].ToString();
                    row["股權代碼"] = dt2.Rows[i]["stock_code"].ToString();
                    row["股權名稱"] = dt2.Rows[i]["stock_name"].ToString();
                    row["股權類別編號"] = dt2.Rows[i]["stock_type"].ToString();
                    row["存入數量"] = dt2.Rows[i]["save_amount"].ToString();
                    row["轉出數量"] = dt2.Rows[i]["draw_amount"].ToString();
                    row["凍結數量"] = dt2.Rows[i]["frozen_amount"].ToString();
                    row["質押數量"] = dt2.Rows[i]["mortgage_amount"].ToString();
                    row["可交易數量"] = dt2.Rows[i]["can_busin_amount"].ToString();
                    row["當前數量"] = dt2.Rows[i]["current_amount"].ToString();
                    row["自然人類別"] = dt2.Rows[i]["employee_type_name"].ToString();
                    row["地區編號"] = dt2.Rows[i]["area_code"].ToString();
                    row["地區名稱"] = dt2.Rows[i]["area_name"].ToString();
                    row["股份權益類別"] = dt2.Rows[i]["stock_bonus_type"].ToString();
                    row["股份權益名稱"] = dt2.Rows[i]["stock_bonus_type_name"].ToString();
                    row["移動電話"] = dt2.Rows[i]["mobile_phone"].ToString();
                    row["摘要"] = dt2.Rows[i]["summary"].ToString();
                    row["銀行編號"] = dt2.Rows[i]["bank_id"].ToString();
                    row["銀行名稱"] = dt2.Rows[i]["bank_name"].ToString();
                    row["銀行帳號"] = dt2.Rows[i]["bankcard_number"].ToString();


                    dt.Rows.Add(row);
                }

                dataGridView1.DataSource = dt;
                dataGridView1.Columns[10].Visible = false;
                dataGridView1.Columns[11].Visible = false;
                dataGridView1.Columns[12].Visible = false;
                dataGridView1.Columns[13].Visible = false;
                dataGridView1.Columns[14].Visible = false;
                dataGridView1.Columns[15].Visible = false;
                dataGridView1.Columns[16].Visible = false;
                dataGridView1.Columns[17].Visible = false;
                dataGridView1.Columns[18].Visible = false;
                dataGridView1.Columns[19].Visible = false;
                dataGridView1.Columns[20].Visible = false;
                dataGridView1.Columns[21].Visible = false;
                dataGridView1.Columns[22].Visible = false;
                dataGridView1.Columns[23].Visible = false;
                dataGridView1.Columns[24].Visible = false;
                dataGridView1.Columns[25].Visible = false;
                dataGridView1.Columns[26].Visible = false;
                dataGridView1.Columns[27].Visible = false;
                dataGridView1.Columns[28].Visible = false;
                dataGridView1.Columns[29].Visible = false;
                dataGridView1.Columns[30].Visible = false;
                dataGridView1.Columns[31].Visible = false;

                queryTitle = "股東名冊\n公司名稱:" + TradeDAL.Stock.GetCompanyNameByCompanyID(TradeDAL.Stock.GetCompanyIDByStockCode(lblstock_code.Text)) + "                  託管代碼:" + lblstock_code.Text + "                       股權總數:" + lbltotal_amount.Text;
                
            }

            else
            {
                MessageBox.Show("股權代碼不存在!", "錯誤提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        private string queryTitle = string.Empty;
        private static DataGridView dgv = null;        // Holds DataGridView Object to print its contents

        private void btnPrint_Click(object sender, EventArgs e)
        {
            Print();
        }

        private void btnCancal_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }


        private void 顯示字段ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (dataGridView1.RowCount > 0)
            {
                Hashtable yestable = new Hashtable();
                Hashtable notable = new Hashtable();
                for (int i = 0; i < dataGridView1.Columns.Count; i++)
                {
                    if (dataGridView1.Columns[i].Visible)
                    {
                        yestable.Add(dataGridView1.Columns[i].DisplayIndex, dataGridView1.Columns[i].HeaderText);
                    }
                    else
                    {
                        notable.Add(dataGridView1.Columns[i].DisplayIndex, dataGridView1.Columns[i].HeaderText);
                    }
                }

                ShowField shouField = new ShowField(yestable, notable, this);
                shouField.ShowDialog();
            }
        }

        private void 打印ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Print();
        }

        public void Print()
        {
            try
            {
                FootText = "\n       XXXXXXX有限公司:                   經辦人:             審覈人:             日期:      年  月  日";
                PrintPreviewDialog ppd = new PrintPreviewDialog();

                PrintDialog MyPrintDialog = new PrintDialog();
                MyPrintDialog.AllowCurrentPage = false;
                MyPrintDialog.AllowPrintToFile = false;
                MyPrintDialog.AllowSelection = true;
                MyPrintDialog.AllowSomePages = false;
                MyPrintDialog.PrintToFile = false;
                MyPrintDialog.ShowHelp = false;
                MyPrintDialog.ShowNetwork = false;

                //if (MyPrintDialog.ShowDialog() != DialogResult.OK)
                //    return;

                MyPrintDialog.ShowDialog();

                // Showing the Print Preview Page
                printDocument1.DocumentName = "股東清冊";
                printDocument1.PrinterSettings = MyPrintDialog.PrinterSettings;
                printDocument1.DefaultPageSettings = MyPrintDialog.PrinterSettings.DefaultPageSettings;
                printDocument1.DefaultPageSettings.Margins = new Margins(5, 5, 10, 5);
                printDocument1.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("A4", 800, 1100);//設置爲A4的紙張

                MyDataGridViewPrinter = new DataGridViewPrinter(dataGridView1, printDocument1, true, true, queryTitle, new Font("宋體", 12, FontStyle.Regular, GraphicsUnit.Point), Color.Black, true, true, FootText, new Font("宋體", 12, FontStyle.Regular, GraphicsUnit.Point), Color.Black);

                ppd.Document = printDocument1;
                ppd.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(), "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            bool more = MyDataGridViewPrinter.DrawDataGridView(e.Graphics);
            if (more == true)
                e.HasMorePages = true;
           
        }

        private void PrintStockList_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }
    }   
}


 


自定義打印類:

using System;
using System.Collections.Generic;

using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;

namespace PrintStock
{
    public class DataGridViewPrinter
    {
        private DataGridView TheDataGridView;   // 需要打印的DataGridView控件

        private PrintDocument ThePrintDocument; // 用於打印的PrintDocument控件

        private bool IsCenterOnPage;            // 決定報表是否打印在頁的上中

        private bool IsWithTitle;               // 決定每頁是否包含標題文字

        private string TheTitleText;            // 如果IsWithTitle爲true,將打印該標題到每一頁上

        private Font TheTitleFont;              // 如果IsWithTitle爲true,將使用該字體打印標題文字

        private Color TheTitleColor;            // 如果IsWithTitle爲true,將使用該顏色打印標題文字

        private Font TheHeaderFont;             // 頭部字體

        private bool IsWithPaging;              // 是否使用分頁

        private Font TheCellFont;               // 單元格字體

        private float TheCellHeight;            // 單元格高度

        static int CurrentRow;                  // 一個靜態變量,用於保持每一行(DataGridView控件中)的打印

        static int PageNumber;                  // 一個靜態變量,用於保存每一頁的頁碼

        private int PageWidth;                  // 每頁的寬度

        private int PageHeight;                 // 每頁的高度

        private int LeftMargin;                 // 每頁的左邊距

        private int TopMargin;                  // 每頁的上邊距

        private int RightMargin;                // 每頁的右邊距

        private int BottomMargin;               // 每頁的下邊距

        private float CurrentY;                 // 該變量用於保存頁的縱座標,因此下一個對象將從這個縱座標開始打印

        private List<float> RowsHeight;         // 每行的高度

        private List<float> ColumnsWidth;       // 每列的寬度

        private float RowHeaderHeight;          // 表頭的高度

        private float TheDataGridViewWidth;     // DataGridView的寬度 

        private float TheDataGridViewHeight;    // DataGridView的高度

        // 保持一個通用的清單舉行啓動/停止點列印刷
        // 這將被用於包裝在特定情況下該DataGridView將不適合在單獨的一頁裏

        private List<int[]> mColumnPoints;      // 列座標

        private List<float> mColumnPointsWidth; // 列座標的寬度

        private int mColumnPoint;               // 列座標

        private bool IsWithFoot;                // 決定每頁是否包含標題文字

        private string TheFootText;             // 如果IsWithFoot爲true,將打印該頁腳到每一頁上

        private Font TheFootFont;               // 如果IsWithFoot爲true,將使用該字體打印頁腳文字

        private Color TheFootColor;             // 如果IsWithFoot爲true,將使用該顏色打印頁腳文字

        /// <summary>
        /// 類的構造函數
        /// </summary>
        /// <param name="aDataGridView">需要打印的DataGridView控件</param>
        /// <param name="aPrintDocument">用於打印的PrintDocument控件</param>
        /// <param name="CenterOnPage">決定報表是否打印在頁的上中</param>
        /// <param name="WithTitle">決定每頁是否包含標題文字</param>
        /// <param name="aTitleText">如果IsWithTitle爲true,將打印該標題到每一頁上</param>
        /// <param name="aTitleFont">如果IsWithTitle爲true,將使用該字體打印標題文字</param>
        /// <param name="aTitleColor">如果IsWithTitle爲true,將使用該顏色打印標題文字</param>
        /// <param name="WithPaging">是否使用分頁</param>
        /// <param name="WithFoot">決定每頁是否包含標題文字</param>
        /// <param name="aFootText">如果IsWithFoot爲true,將打印該頁腳到每一頁上</param>
        /// <param name="aFootFont">如果IsWithFoot爲true,將使用該字體打印頁腳文字</param>
        /// <param name="aFootColor">如果IsWithFoot爲true,將使用該顏色打印頁腳文字</param>
        public DataGridViewPrinter(
            DataGridView aDataGridView,
            PrintDocument aPrintDocument,
            bool CenterOnPage,
            bool WithTitle,
            string aTitleText,
            Font aTitleFont,
            Color aTitleColor,
            bool WithPaging,
            bool WithFoot,
            string aFootText,
            Font aFootFont,
            Color aFootColor
            )
        {
            TheDataGridView = aDataGridView;    // 需要打印的DataGridView控件

            ThePrintDocument = aPrintDocument;  // 用於打印的PrintDocument控件

            IsCenterOnPage = CenterOnPage;      // 決定報表是否打印在頁的上中

            IsWithTitle = WithTitle;            // 決定每頁是否包含標題文字

            TheTitleText = aTitleText;          // 如果IsWithTitle爲true,將打印該標題到每一頁上

            TheTitleFont = aTitleFont;          // 如果IsWithTitle爲true,將使用該字體打印標題文字

            TheTitleColor = aTitleColor;        // 如果IsWithTitle爲true,將使用該顏色打印標題文字

            IsWithPaging = WithPaging;          // 是否使用分頁

            IsWithFoot = WithFoot;              // 決定每頁是否包含標題文字

            TheFootText = aFootText;            // 如果IsWithFoot爲true,將打印該頁腳到每一頁上

            TheFootFont = aFootFont;            // 如果IsWithFoot爲true,將使用該字體打印頁腳文字

            TheFootColor = aFootColor;          // 如果IsWithFoot爲true,將使用該顏色打印頁腳文字

            PageNumber = 0;                     // 頁面爲0 

            RowsHeight = new List<float>();     // 初始化每行的高度列表

            ColumnsWidth = new List<float>();   // 初始化每列的寬度列表

            mColumnPoints = new List<int[]>();  // 初始化列座標

            mColumnPointsWidth = new List<float>();//初始化列座標寬度

            // 計算每頁寬度和高度
            //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;
            //}

            // 計算頁邊距
            LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left;

            TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top;

            RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right;

            BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom;

            // 首先,當前行打印是第一排在DataGridView控制
            CurrentRow = 0;
        }

        // 這個方法的功能是計算高度,計算每一行(包括標題行),每一列的寬度(根據最長的文本在所有的單元格,包括頁眉單元格),和整個DataGridView寬度
        private void Calculate(Graphics g)
        {
            if (PageNumber == 0) // 僅僅計算一次
            {
                // 存儲有序浮點數對,通常爲矩形的寬度和高度
                SizeF tmpSize = new SizeF();

                Font tmpFont;// 零時字體變量

                float tmpWidth;// 零時長度變量

                TheDataGridViewWidth = 0;// 設置DataGridView控件長度爲0

                // 循環DataGridView控件的所有列
                for (int i = 0; i < TheDataGridView.Columns.Count; i++)
                {
                    // 讀取DataGridView控件表頭樣式的字體保存在零時變量裏
                    tmpFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
                    if (tmpFont == null) // 如果DataGridView控件表頭樣式的字體爲空,則使用它的默認字體
                        tmpFont = TheDataGridView.DefaultCellStyle.Font;
                    Font newFont = new Font("宋體", 9f, FontStyle.Regular);
                    tmpFont = newFont;

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

                    tmpWidth = tmpSize.Width;
                    if (RowHeaderHeight < tmpSize.Height)
                        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;

                        if (TheCellFont != null)
                        {
                            tmpFont = TheCellFont;
                        }

                        if (TheCellHeight < tmpFont.Height)
                            TheCellHeight = tmpFont.Height;

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

                        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);
                }

                //定義啓動/停止柱分基於網頁寬度和DataGridView寬度
                //我們將利用這個確定繪製柱,以及如何將每一頁包裝處理
                //默認情況下,包裝,將腕高低最大數量的頁面將會列一個確定的
                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;
            }
        }

        /// <summary>
        /// 這個方法的作用是打印標題,頁碼和表頭
        /// </summary>
        /// <param name="g"></param> 
        private void DrawHeader(Graphics g)
        {
            CurrentY = (float)TopMargin;

            // 如果isWithPaging設置爲true,打印頁碼
            if (IsWithPaging)
            {

                TheDataGridViewHeight = TheDataGridView.ColumnHeadersHeight * TheDataGridView.Rows.Count;
                int availableHeight = PageHeight - TopMargin - BottomMargin - 60;
                int pages = (int)TheDataGridViewHeight / availableHeight;
                //if ((int)TheDataGridViewHeight % availableHeight != 0)
                //    pages++;
                TheDataGridViewHeight = TheDataGridViewHeight + pages * TheDataGridView.ColumnHeadersHeight;
                int pageCount = (int)TheDataGridViewHeight / availableHeight;
                if ((int)TheDataGridViewHeight % availableHeight != 0)
                    pageCount++;

                PageNumber++;
                if (PageNumber > pageCount)//防止打印到文件之後頁面一直增大 出現 當前第6頁,共5頁的錯誤
                    PageNumber = PageNumber - pageCount;
                string PageString = "當前第 " + PageNumber.ToString() + " 頁,共 " + pageCount + " 頁";
                //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("宋體", 12, FontStyle.Regular, GraphicsUnit.Point);

                RectangleF PageStringRectangle = new RectangleF((float)LeftMargin, CurrentY + 6, (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;
            }

            // 如果isWithPaging設置爲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;
            }

            // 啓動x座標計算的印刷工藝將開始
            float CurrentX = (float)LeftMargin;
            if (IsCenterOnPage)
                CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;

            // 設置表頭前景顏色
            Color HeaderForeColor = TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
            if (HeaderForeColor.IsEmpty) // 如果表頭前景顏色爲空,使用它的默認前景顏色
                HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
            SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor);

            // 設置表頭背景顏色
            Color HeaderBackColor = TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor;
            if (HeaderBackColor.IsEmpty) // 如果表頭背景顏色爲空,使用它的默認背景顏色
                HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor;
            SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor);

            // 設置將會用來畫線和長方形(源自GridColor屬性的DataGridView控制)
            Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);

            // 設置表頭字體
            Font HeaderFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
            if (HeaderFont == null) // 如果表頭字體爲空,使用它的默認樣式
                HeaderFont = TheDataGridView.DefaultCellStyle.Font;
            //Font newFont = new Font("華文行楷", 11.5f, FontStyle.Regular);
            //HeaderFont = newFont;

            if (this.TheHeaderFont != null)
            {
                HeaderFont = TheHeaderFont;
            }

            // HeaderBounds計算及作圖      
            RectangleF HeaderBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowHeaderHeight + 6);
            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 (!TheDataGridView.Columns[i].Visible) continue; // 如果列未隱藏,忽略它重複

                ColumnWidth = ColumnsWidth[i];

                // 檢查當前單元格對齊並將其應用到單元格樣式
                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;

                float headerY = (this.RowHeaderHeight - HeaderFont.Height + 6) / 2;


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

                // 打印單元格文字

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

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

                CurrentX += ColumnWidth;
            }

            CurrentY += RowHeaderHeight + 6;
        }

        //該方法打印行,裝在一個頁面
        //當它將返回true,意味着有更多的行還不打印出來,那麼的另一種頁面行動是必要的
        //什麼時候將返回false,意味着所有的行打印(當前行參數達到最後一行的控制和DataGridView沒有進一步的頁面打印行動是必要的
        private bool DrawRows(Graphics g)
        {
            // 畫邊框
            Pen TheLinePen = new Pen(TheDataGridView.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 < TheDataGridView.Rows.Count)
            {
                if (TheDataGridView.Rows[CurrentRow].Visible) // 當前行打印的單元格只有那一行是看得見的
                {
                    // 設置行的樣式
                    RowFont = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font;
                    if (RowFont == null) // 如果行沒有樣式,就使用它的默認樣式
                        RowFont = TheDataGridView.DefaultCellStyle.Font;
                    //Font newFont = new Font(FontFamily.GenericSansSerif, 15f, FontStyle.Regular);
                    //RowFont = newFont;

                    if (TheCellFont != null)
                    {
                        RowFont = TheCellFont;
                    }

                    // 設置行前景樣式
                    RowForeColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor;
                    if (RowForeColor.IsEmpty) // 如果行沒有前景樣式,就用它的默認前景樣式
                        RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
                    RowForeBrush = new SolidBrush(RowForeColor);

                    // 設置行和交替行的背景顏色
                    RowBackColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor;
                    if (RowBackColor.IsEmpty) // 如果行和交替行沒有背景顏色,就使用它的默認背景顏色
                    {
                        RowBackBrush = new SolidBrush(TheDataGridView.DefaultCellStyle.BackColor);
                        RowAlternatingBackBrush = new SolidBrush(TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor);
                    }
                    else // 如果有一種特別的RowBack風格的CurrentRow,然後用它對於RowBack和RowAlternatingBack風格
                    {
                        RowBackBrush = new SolidBrush(RowBackColor);
                        RowAlternatingBackBrush = new SolidBrush(RowBackColor);
                    }

                    // 啓動x座標計算的印刷工藝將開始
                    CurrentX = (float)LeftMargin;
                    if (IsCenterOnPage)
                        CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;

                    // 計算整個當前行的界限              
                    RowBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowsHeight[CurrentRow] + 10);

                    // 填充當前行的後面
                    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 (!TheDataGridView.Columns[CurrentCell].Visible) continue; // If the cell is belong to invisible column, then ignore this iteration

                        // 檢查當前單元格對齊並將其應用到非單元格格式
                        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] + 10);

                        // 打印單元格文字
                        //MessageBox.Show(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString());
                        g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, new Rectangle((int)CellBounds.X, (int)(CellBounds.Y + 6), (int)CellBounds.Width + 20, (int)CellBounds.Height), CellFormat);

                        // 打印單元格界限
                        if (TheDataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None) // 畫出單元格邊界只有在單元格邊框樣式不是一個也沒有
                            g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow] + 10);

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

                    //檢查如果縱座標超過一頁是拉
                    //如果是那樣的話,退出函數返回true,另一個PagePrint意義行動是必要的
                    if ((int)CurrentY > (PageHeight - TopMargin - BottomMargin - 60))
                    {
                        CurrentRow++;
                        return true;
                    }
                }
                CurrentRow++;
            }

            CurrentRow = 0;
            mColumnPoint++; // 繼續打印列的下一組

            if (mColumnPoint == mColumnPoints.Count) // 這意味着所有欄目要打印
            {
                mColumnPoint = 0;
                return false;
            }
            else
                return true;
        }

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

                RectangleF FootRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(TheFootText, TheFootFont).Height);

                g.DrawString(TheFootText, TheFootFont, new SolidBrush(TheFootColor), FootRectangle, FootFormat);

                CurrentY += g.MeasureString(TheFootText, TheFootFont).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;
            ////Font newFont = new Font("華文行楷", 11.5f, FontStyle.Regular);
            ////HeaderFont = newFont;

            //if (this.TheHeaderFont != null)
            //{
            //    HeaderFont = TheHeaderFont;
            //}


            //// 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 (!TheDataGridView.Columns[i].Visible) continue; // If the column is not visible then ignore this iteration

            //    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;

            //    float headerY = (this.RowHeaderHeight - HeaderFont.Height) / 2;


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

            //    // Printing the cell text

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

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

            //    CurrentX += ColumnWidth;
            //}

            //CurrentY += RowHeaderHeight;
        }

        /// <summary>
        /// 畫出DataGridView
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public bool DrawDataGridView(Graphics g)
        {
            try
            {
                Calculate(g);
                DrawHeader(g);
                bool bContinue = DrawRows(g);
                DrawFooter(g);
                return bContinue;
            }
            catch (Exception ex)
            {
                MessageBox.Show("打印失敗: " + ex.Message.ToString(), Application.ProductName + " 錯誤提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 要個性化打印,必須調
        /// </summary>
        /// <param name="cellFont"></param>
        /// <param name="columnFont"></param>
        /// <param name="cellHeight"></param>
        /// <param name="columnHeight"></param>
        public void setPrintFont(Font cellFont, Font columnFont, float cellHeight, float columnHeight)
        {
            this.RowHeaderHeight = columnHeight;
            this.TheHeaderFont = columnFont;
            this.TheCellFont = cellFont;
            this.TheCellHeight = cellHeight;
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章