![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public class Printer { private DataGridView dataview; private PrintDocument printDoc; private Font printFontStyle; //打印有效区域的宽度 int width; int height; int columns; double Rate;//打印宽度和纸张的比例 bool hasMorePage = false;//是否跨页 int currRow = 0; int rowHeight = 61; //打印页数 int PageNumber; //当前打印页的行数,默认打印行数 int pageSize = 20; //当前打印的页码 int PageIndex=0; int AreaHeight; private int PageWidth; //打印纸的宽度 private int PageHeight; //打印纸的高度 private int LeftMargin; //有效打印区距离打印纸的左边大小 private int TopMargin;//有效打印区距离打印纸的上面大小 private int RightMargin;//有效打印区距离打印纸的右边大小 private int BottomMargin;//有效打印区距离打印纸的下边大小 int rows; private string[] footer; //// <summary> /// 构造函数 /// </summary> /// <param name="dataview">要打印的DateGridView</param> /// <param name="printDoc">PrintDocument用于获取打印机的设置</param> public Printer(DataGridView dataview, Font fontStyle, PrintDocument printDoc, string[] footer) { this.footer = footer; this.dataview = dataview; this.printDoc = printDoc; this.printFontStyle = fontStyle; //PageIndex = 0; //获取打印数据的具体行数 this.rows = dataview.RowCount-1; this.columns = dataview.ColumnCount; //判断打印设置是否是横向打印 if (!printDoc.DefaultPageSettings.Landscape) { PageWidth = printDoc.DefaultPageSettings.PaperSize.Width; PageHeight = printDoc.DefaultPageSettings.PaperSize.Height; } else { PageHeight = printDoc.DefaultPageSettings.PaperSize.Width; PageWidth = printDoc.DefaultPageSettings.PaperSize.Height; } LeftMargin = printDoc.DefaultPageSettings.Margins.Left<20?20: printDoc.DefaultPageSettings.Margins.Left; TopMargin = printDoc.DefaultPageSettings.Margins.Top<20?20: printDoc.DefaultPageSettings.Margins.Top; RightMargin = printDoc.DefaultPageSettings.Margins.Right < 20 ? 20: printDoc.DefaultPageSettings.Margins.Right; BottomMargin = printDoc.DefaultPageSettings.Margins.Bottom < 20 ? 20 : printDoc.DefaultPageSettings.Margins.Bottom; height = PageHeight - TopMargin - BottomMargin - 5; width = PageWidth - LeftMargin - RightMargin - 5; double tempheight = height; double temprowHeight = rowHeight; while (true) { string temp = Convert.ToString(tempheight / Math.Round(temprowHeight, 3)); int i = temp.IndexOf('.'); double tt = 100; if (i != -1) { tt = Math.Round(Convert.ToDouble(temp.Substring(temp.IndexOf('.'))), 3); } if (tt <= 0.01) { rowHeight = Convert.ToInt32(temprowHeight); break; } else { temprowHeight = temprowHeight + 0.01; } } pageSize = height / rowHeight; if ((rows + 1) <= pageSize) { pageSize = rows + 1; PageNumber = 1; } else { PageNumber = rows / (pageSize - 1); if (rows % (pageSize - 1) != 0) { PageNumber = PageNumber + 1; } } } /// <summary> /// 初始化打印 /// </summary> private void InitPrint() { PageIndex = PageIndex + 1; if (PageIndex == PageNumber) { hasMorePage = false; if (PageIndex != 1) { pageSize = rows % (pageSize - 1) + 1; } } else { hasMorePage = true; } } //打印头 private void DrawHeader(Graphics g) { //根据比例调整字体大小 double newsize = (printFontStyle.Size / Rate); if (newsize <= 10) { newsize = 10; } Font newfont = new Font("宋体", (float)newsize, FontStyle.Regular); int temptop = (rowHeight / 2) + TopMargin + 1; int templeft = LeftMargin + 1; for (int i = 0; i < this.columns; i++) { string headString = this.dataview.Columns[i].HeaderText; float fontHeight = g.MeasureString(headString, newfont).Height; float fontwidth = g.MeasureString(headString, newfont).Width; float temp = temptop - (fontHeight) / 3; int colWidth = (int)(this.dataview.Columns[i].Width / Rate); int newtempleft = 0; //判读内容是否比宽度长 if (colWidth > fontwidth)//居中 { newtempleft = templeft + (int)((float)colWidth- fontwidth) / 2 + 1; } else { while (true) { if (fontwidth <= colWidth) { break; } else { headString = headString.Substring(0, headString.Length - 1); fontwidth = g.MeasureString(headString, newfont).Width; } } newtempleft = templeft + (int)((float)colWidth - fontwidth) / 2 + 1; } g.DrawString(headString, newfont, Brushes.Black, new PointF(newtempleft, temp)); templeft = templeft + (int)(this.dataview.Columns[i].Width / Rate) + 1; } } //画表格 private void DrawTable(Graphics g) { Rectangle border = new Rectangle(LeftMargin, TopMargin, width, (pageSize) * rowHeight); g.DrawRectangle(new Pen(Brushes.Black, 1), border); for (int i = 1; i < pageSize; i++) { if (i != 1) { g.DrawLine(new Pen(Brushes.Black, 1), new Point(LeftMargin + 1, (rowHeight * i) + TopMargin + 1), new Point(width + LeftMargin, (rowHeight * i) + TopMargin + 1)); } else { g.DrawLine(new Pen(Brushes.Black, 1), new Point(LeftMargin + 1, (rowHeight * i) + TopMargin + 1), new Point(width + LeftMargin, (rowHeight * i) + TopMargin + 1)); } } //计算出列的总宽度和打印纸比率 Rate = Convert.ToDouble(GetDateViewWidth()) / Convert.ToDouble(width); int tempLeft = LeftMargin + 1; int endY = (pageSize) * rowHeight + TopMargin; for (int i = 1; i < columns; i++) { tempLeft = tempLeft + 1 + (int)(this.dataview.Columns[i - 1].Width / Rate); g.DrawLine(new Pen(Brushes.Black, 1), new Point(tempLeft, TopMargin), new Point(tempLeft, endY)); } } /// <summary> /// 获取打印的列的总宽度 /// </summary> /// <returns></returns> private int GetDateViewWidth() { int total = 0; for (int i = 0; i < this.columns; i++) { total = total + this.dataview.Columns[i].Width; } return total; } //打印行数据 private void DrawRows(Graphics g) { //Font font = new Font("宋体", 11, FontStyle.Regular); //根据比例调整字体大小 double newsize = (printFontStyle.Size / Rate); if (newsize <= 10) { newsize = 10; } Font newfont = new Font("宋体", (float)newsize, FontStyle.Regular); int temptop = (rowHeight / 2) + TopMargin + 1 + rowHeight;//垂直居中 for (int i = currRow; i < pageSize + currRow - 1; i++) { int templeft = LeftMargin + 1; for (int j = 0; j < columns; j++) { string headString = this.dataview.Rows[i].Cells[j].Value==null?"":this.dataview.Rows[i].Cells[j].Value.ToString(); float fontHeight = g.MeasureString(headString, newfont).Height; float fontwidth = g.MeasureString(headString, newfont).Width; int colWidth = (int)(this.dataview.Columns[j].Width / Rate); float temp = temptop - (fontHeight) / 3; int newtempleft = 0; //判读内容是否比宽度长 if (colWidth > fontwidth)//居中 { newtempleft = templeft + (int)((float)colWidth - fontwidth) / 2 + 1; g.DrawString(headString, newfont, Brushes.Black, new PointF(newtempleft, temp)); } else { // int line= Math.Ceiling((double)(fontwidth / colWidth)); string tempi = Convert.ToString((double)(fontwidth /colWidth)); string []tei = tempi.Split('.'); int line = int.Parse(tei[0])+ (tei.Count()>0?1:0); int lineWidth = (int)headString.Length / line; string newHeadString = ""; string lastHeadString = headString; int linti = 0; while (true) { linti++; newHeadString += lastHeadString.Substring(0, lineWidth> lastHeadString.Length? lastHeadString.Length: lineWidth) + "\r\n"; if (lineWidth <= lastHeadString.Length) { lastHeadString = lastHeadString.Substring(lineWidth, lastHeadString.Length - lineWidth); } else { lastHeadString = ""; } if(lastHeadString=="") break; //if (fontwidth <= colWidth) //{ // break; //} //else //{ // headString = headString.Substring(0, headString.Length - 1); // fontwidth = g.MeasureString(headString, newfont).Width; //} } headString = newHeadString.TrimEnd('n','\\','r'); newtempleft = templeft + (int)((float)colWidth - fontwidth/ line) / 2 + 1; //newtempleft = templeft; temp = linti * fontHeight > rowHeight? (temp- fontHeight) :(temp-(fontHeight / 3)* (line-1)); g.DrawString(headString, newfont, Brushes.Black, new PointF(newtempleft, temp )); } templeft = templeft + (int)(this.dataview.Columns[j].Width / Rate) + 1; } temptop = temptop + rowHeight; } currRow = pageSize + currRow - 1; AreaHeight = temptop; } /// <summary> /// 在PrintDocument中的PrintPage方法中调用 /// </summary> /// <param name="g">传入PrintPage中PrintPageEventArgs中的Graphics</param> /// <returns>是否还有打印页 有返回true,无则返回false</returns> public bool Print(Graphics g) { InitPrint(); DrawTable(g); DrawHeader(g); DrawRows(g); //打印页码 string pagestr = PageIndex + " / " + PageNumber; Font font = new System.Drawing.Font("宋体", 11, FontStyle.Regular); g.DrawString(pagestr, font, Brushes.Black, new PointF((PageWidth / 2) - g.MeasureString(pagestr, font).Width, PageHeight - (BottomMargin / 2) - g.MeasureString(pagestr, font).Height)); // 打印查询的功能项名称 return hasMorePage; } }
![](https://i-blog.csdnimg.cn/blog_migrate/daf146c98c5696c2128f91250e76527a.png)
1.打印预览调用
Font txtFont = new Font("宋体", 12, FontStyle.Regular);//正文字体
newPrint = new Printer(printDataGridView, txtFont, pd, null);
pd.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
if (printDataGridView.Rows.Count > 0)
{
bool hasMorePage=newPrint.Print(ev.Graphics);
ev.HasMorePages = hasMorePage;
}
else
{
MessageBox.Show("没有需要打印的数据");
}
2.打印预览调用
if (!flag)
{
Font txtFont = new Font("宋体", 12, FontStyle.Regular);//正文字体
newPrint = new Printer(printDataGridView, txtFont, pd, null);
pd.PrintPage -= new PrintPageEventHandler(printDocument_PrintPage);
pd.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
}
previewDialog.Document = pd;//指向要打印的对象
previewDialog.ShowDialog();//打印预览对话框显示出来
3.打印设置
private void printDialog_Click(object sender, EventArgs e)
{
pageSetupDialog.Document = pd;
pageSetupDialog.ShowDialog();
}
效果图: