
能实现如上图的的打印功能。
·所有字体,边距,header 高,行高,都可以自定义。
·支持自动计算每页行数与每页固定行数。
·支持页脚显示页数。
由于自己用和本人比较懒,所以把属性都设置成公有,赋值的时候小心。
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Printing; using System.Data;
using System.Windows.Forms;
namespace cjManager { public class cutePrinter { private DataGrid dataGrid; private PrintDocument printDocument; private PageSetupDialog pageSetupDialog; private PrintPreviewDialog printPreviewDialog;
private string title=""; int currentPageIndex=0; int rowCount=0; int pageCount=0;
int titleSize=16; bool isCustomHeader=false; //Brush alertBrush=new SolidBrush(Color.Red);
string[] header=null;//如果自定义就填入字符串,如果需要斜线分隔,就用\表示,例如:个数#名字 其中#为splitChar string[] uplineHeader=null;//上行文字数组 int[] upLineHeaderIndex=null;//上行的文字index,如果没有上行就设为-1; //bool isEveryPagePrintHead=true;//是否每一页都要打印列头。
public bool isEveryPagePrintTitle=false;//是否每一页都要打印标题。 public int headerHeight=50;//标题高度。 public int topMargin=60; //顶边距 public int cellTopMargin=6;//单元格顶边距 public int cellLeftMargin=4;//单元格左边距 public char splitChar='#';//当header要用斜线表示的时候 public string falseStr="×";//如果传进来的dataGrid中有 false,把其转换得字符。 public string trueStr="√";//如果传进来的dataGrid中有 true,把其转换得字符。 public int pageRowCount=7;//每页行数 public int rowGap = 30;//行高 public int colGap = 5;//每列间隔 public int leftMargin = 50;//左边距 public Font titleFont=new Font("Arial",14);//标题字体 public Font font = new Font("Arial", 10);//正文字体 public Font headerFont = new Font("Arial", 9, FontStyle.Bold);//列名标题 public Font footerFont=new Font("Arial",8);//页脚显示页数的字体 public Font upLineFont=new Font("Arial",9, FontStyle.Bold);//当header分两行显示的时候,上行显示的字体。 public Font underLineFont=new Font("Arial",8);//当header分两行显示的时候,下行显示的字体。 public Brush brush = new SolidBrush(Color.Black);//画刷 public bool isAutoPageRowCount=true;//是否自动计算行数。 public int buttomMargin=80;//底边距 public bool needPrintPageIndex=true;//是否打印页脚页数
//string filterStr="";
public cutePrinter(DataGrid dataGrid,string title,int titleSize) { this.title=title; //this.titleSize=titleSize;
this.dataGrid = dataGrid; printDocument = new PrintDocument(); printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);
} public cutePrinter(DataGrid dataGrid,string title) { this.title=title;
this.dataGrid = dataGrid; printDocument = new PrintDocument(); printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage); } public cutePrinter(DataGrid dataGrid) { this.dataGrid = dataGrid; printDocument = new PrintDocument(); printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage); }
public bool setTowLineHeader(string[] upLineHeader,int[] upLineHeaderIndex) { this.uplineHeader=upLineHeader; this.upLineHeaderIndex=upLineHeaderIndex; this.isCustomHeader=true; return true; } public bool setHeader(string[] header) { this.header=header; return true;
}
private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) {
int width=e.PageBounds.Width; int height=e.PageBounds.Height;
if(this.isAutoPageRowCount) pageRowCount=(int)((height-this.topMargin-titleSize-this.headerFont.Height-this.headerHeight-this.buttomMargin)/this.rowGap);
pageCount=(int)(rowCount/pageRowCount); if(rowCount%pageRowCount>0) pageCount++;
int xoffset=(int)((width-e.Graphics.MeasureString(this.title,this.titleFont).Width)/2); int colCount = 0; int x = 0; int y =topMargin; string cellValue = "";
int startRow=currentPageIndex*pageRowCount; int endRow=startRow+this.pageRowCount<rowCount?startRow+pageRowCount:rowCount; int currentPageRowCount=endRow-startRow;
if(this.currentPageIndex==0 || this.isEveryPagePrintTitle) { e.Graphics.DrawString(this.title,titleFont,brush,xoffset,y); y+=titleSize; }
colCount = dataGrid.TableStyles[0].GridColumnStyles.Count;
y += rowGap; x = leftMargin;
DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);//最左边的竖线
int lastIndex=-1; int lastLength=0; int indexj=-1;
for(int j = 0; j < colCount; j++) { int colWidth=dataGrid.TableStyles[0].GridColumnStyles[j].Width; if( colWidth> 0) { indexj++; if(this.header==null || this.header[indexj]=="") cellValue = dataGrid.TableStyles[0].GridColumnStyles[j].HeaderText; else cellValue=header[indexj];
if(this.isCustomHeader) { if(this.upLineHeaderIndex[indexj]!=lastIndex) { if(lastLength>0 && lastIndex>-1)//开始画上一个upline { string upLineStr=this.uplineHeader[lastIndex]; int upXOffset=(int)((lastLength-e.Graphics.MeasureString(upLineStr,this.upLineFont).Width)/2); if(upXOffset<0) upXOffset=0; e.Graphics.DrawString(upLineStr,this.upLineFont,brush,x-lastLength+upXOffset,y+(int)(this.cellTopMargin/2));
DrawLine(new Point(x-lastLength,y+(int)(this.headerHeight/2)),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);//中线 DrawLine(new Point(x,y),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics); } lastIndex=this.upLineHeaderIndex[indexj]; lastLength=colWidth+colGap; } else { lastLength+=colWidth+colGap; } }
//int currentY=y+cellTopMargin; int Xoffset=10; int Yoffset=20; int leftWordIndex=cellValue.IndexOf(this.splitChar); if(this.upLineHeaderIndex!=null && this.upLineHeaderIndex[indexj]>-1) { if(leftWordIndex>0) { string leftWord=cellValue.Substring(0,leftWordIndex); string rightWord=cellValue.Substring(leftWordIndex+1,cellValue.Length-leftWordIndex-1); //上面的字 Xoffset=(int)(colWidth+colGap-e.Graphics.MeasureString(rightWord,this.upLineFont).Width); Yoffset=(int)(this.headerHeight/2-e.Graphics.MeasureString("a",this.underLineFont).Height);
//Xoffset=6; //Yoffset=10; e.Graphics.DrawString(rightWord,this.underLineFont,brush,x+Xoffset-4,y+(int)(this.headerHeight/2)); e.Graphics.DrawString(leftWord,this.underLineFont,brush,x+2,y+(int)(this.headerHeight/2)+(int)(this.cellTopMargin/2)+Yoffset-2); DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x+colWidth+colGap,y+headerHeight),e.Graphics); x += colWidth + colGap; DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics); } else {
e.Graphics.DrawString(cellValue, headerFont, brush, x, y+(int)(this.headerHeight/2)+(int)(this.cellTopMargin/2)); x += colWidth + colGap; DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics); } } else { if(leftWordIndex>0) { string leftWord=cellValue.Substring(0,leftWordIndex); string rightWord=cellValue.Substring(leftWordIndex+1,cellValue.Length-leftWordIndex-1); //上面的字 Xoffset=(int)(colWidth+colGap-e.Graphics.MeasureString(rightWord,this.upLineFont).Width); Yoffset=(int)(this.headerHeight-e.Graphics.MeasureString("a",this.underLineFont).Height);
e.Graphics.DrawString(rightWord,this.headerFont,brush,x+Xoffset-4,y+2); e.Graphics.DrawString(leftWord,this.headerFont,brush,x+2,y+Yoffset-4); DrawLine(new Point(x,y),new Point(x+colWidth+colGap,y+headerHeight),e.Graphics); x += colWidth + colGap; DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics); } else { e.Graphics.DrawString(cellValue, headerFont, brush, x, y+cellTopMargin); x += colWidth + colGap; DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics); } }
} } ////循环结束,画最后一个的upLine if(this.isCustomHeader) { if(lastLength>0 && lastIndex>-1)//开始画上一个upline { string upLineStr=this.uplineHeader[lastIndex]; int upXOffset=(int)((lastLength-e.Graphics.MeasureString(upLineStr,this.upLineFont).Width)/2); if(upXOffset<0) upXOffset=0; e.Graphics.DrawString(upLineStr,this.upLineFont,brush,x-lastLength+upXOffset,y+(int)(this.cellTopMargin/2));
DrawLine(new Point(x-lastLength,y+(int)(this.headerHeight/2)),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);//中线 DrawLine(new Point(x,y),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics); } } int rightBound=x;
DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics); //最上面的线
//DrawLine(new Point(leftMargin,y+this.headerHeight),new Point(rightBound,y+this.headerHeight),e.Graphics);//列名的下面的线
y+=this.headerHeight;
//print all rows for(int i = startRow; i < endRow; i++) { x = leftMargin; for(int j = 0; j < colCount; j++) { if(dataGrid.TableStyles[0].GridColumnStyles[j].Width > 0) { cellValue = dataGrid[i,j].ToString(); if(cellValue=="False") cellValue=falseStr; if(cellValue=="True") cellValue=trueStr; e.Graphics.DrawString(cellValue, font, brush, x+this.cellLeftMargin, y+cellTopMargin); x += dataGrid.TableStyles[0].GridColumnStyles[j].Width + colGap; y = y + rowGap * (cellValue.Split(new char[] {'\r', '\n'}).Length - 1); } } DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics); y += rowGap; } DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics);
currentPageIndex++;
if(this.needPrintPageIndex) e.Graphics.DrawString("共 "+pageCount.ToString()+" 页,当前第 "+this.currentPageIndex.ToString()+" 页",this.footerFont,brush,width-200,(int)(height-this.buttomMargin/2-this.footerFont.Height));
string s = cellValue; string f3 = cellValue;
if(currentPageIndex<pageCount) { e.HasMorePages=true; } else { e.HasMorePages=false; this.currentPageIndex=0; } //iPageNumber+=1; } private void DrawLine(Point sp,Point ep,Graphics gp) { Pen pen=new Pen(Color.Black); gp.DrawLine(pen,sp,ep); }
public PrintDocument GetPrintDocument() { return printDocument; }
public void Print() { rowCount=0;
if(dataGrid.DataSource.GetType().ToString() == "System.Data.DataTable") { rowCount = ((DataTable)dataGrid.DataSource).Rows.Count; } else if(dataGrid.DataSource.GetType().ToString() == "System.Collections.ArrayList") { rowCount = ((ArrayList)dataGrid.DataSource).Count; }
try { pageSetupDialog = new PageSetupDialog(); pageSetupDialog.Document = printDocument; pageSetupDialog.ShowDialog();
printPreviewDialog = new PrintPreviewDialog(); printPreviewDialog.Document = printDocument; printPreviewDialog.Height = 600; printPreviewDialog.Width = 800; printPreviewDialog.ShowDialog(); } catch(Exception e) { throw new Exception("Printer error." + e.Message); }
} } }
//用法示例,显示结果如顶图。
private void bnPrint_Click(object sender, System.EventArgs e) { cutePrinter dgp=new cutePrinter(this.dataGrid1,this.dlSearchYear.Text+"年"+"专业",16); string[] uplinestr={"呵呵,hehe","xixi"}; string[] header={"呵呵#xixi","Hee#xcc","kdfj#djjj","kk#jj","kdjf","","","",""}; dgp.setHeader(header);//如果不用改原header就不用赋值。 //注意,这里的列不包括width==0的列 int[] uplineindex={-1,-1,0,0,0,-1,1,1};//注意,这里的列不包括width==0的列 dgp.setTowLineHeader(uplinestr,uplineindex); dgp.Print(); } 
|