现在的位置: 首页 > 综合 > 正文

打印DataGridView数据,可以加眉头和页尾

2013年09月29日 ⁄ 综合 ⁄ 共 31030字 ⁄ 字号 评论关闭

 由于数据保密性故将图片处理,代码先贴上

 

 

获取数据代码:

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

抱歉!评论已关闭.