由于数据保密性故将图片处理,代码先贴上
获取数据代码:
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; } } }