⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misprinter.cs

📁 C#实现简单报表打印 进销存真正源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
			PrinterPageSetting	printerPageSetting;		
			printerPageSetting = new PrinterPageSetting(mPrintDocument);
			printerPageSetting.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);

			printerPageSetting.ShowPrintPreviewDialog();		
		}

		//绘制		
		private void PrintPageEventHandler(object obj,System.Drawing.Printing.PrintPageEventArgs ev)
		{
			Graphics g = ev.Graphics ;
			
			this.mGraphics = g;

			g.Clear(this.BackColor);

			try
			{	
				bool blnMore = this.Draw(g);
				
				if (blnMore)
				{
					ev.HasMorePages = true;
					mCurrentPageIndex++;
				}
				else
				{
					ev.HasMorePages = false;	
					this.mCurrentPageIndex = 1;
				}
			}
			catch(Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}
		}


		/// 对象打印接口
		private void OutObject(IDraw outer)
		{
//			this.mGraphics.ResetTransform();
			if (outer != null)
			{
				outer.Graphics = this.mGraphics;
				outer.PrintDocument = this.mPrintDocument;
				outer.Sewing = this.Sewing;
				outer.RectangleF = new RectangleF(X,Y,Width,outer.Height);	
				outer.Draw();
				this.Y  += outer.RectangleF.Height;
			}
		}

		#region 绘制过程

		//*****这段代码确实太长了,应该用重构的手法进行处理,不过,我这里主要是让大家从头到尾的顺利的看下去
		//*****在下一个版本的源代码中我会整理,大家也可以试一试。
		private bool Draw(Graphics g)
		{
			bool blnHasMorePage = false;		//是否还有下一页标记

			if (this._body.Rows < 0)
			{
				throw new Exception("打印主要网格不能为空,请用Body设置!");
			}

			Printer printer = new Printer();
			printer.Graphics = g;
			printer.PrintDocument = this.mPrintDocument;
			printer.Sewing = this.Sewing;
			
			//初起打印起点坐标及打印区域的宽
			Y = printer.PrinterMargins.Top;
			X = printer.PrinterMargins.Left;
			Width = printer.PrinterMargins.Width;

			#region 画打印区域及装订线
			if (IsPrinterMargins)
			{
				printer.DrawPrinterMargins();
			}
			if (IsSewingLine && _sewing.Margin > 0)
			{
				//对象的线长小于0则自动设置
				if (this._sewing.LineLen < 0)
				{
					if (this._sewing.SewingDirection == SewingDirectionFlag.Left)
					{
						this._sewing.LineLen = printer.PageHeight;
					}
					else if (this._sewing.SewingDirection == SewingDirectionFlag.Top)
					{
						this._sewing.LineLen = printer.PageWidth;
					}

				}
				printer.Sewing = this._sewing;
				printer.DrawSewing();
			}
			#endregion
			
			//正标题每页必重复打印,无需判断
			if (_title != null)
			{	
				OutObject(_title);
			}

			if (mCurrentPageIndex == 1 || _caption.IsDrawAllPage)
			{
				if (_caption != null)
				{	
					if (_title != null)
					{
						_caption.MoveY = this._title.Height + 5;
					}
					OutObject(_caption);
				}
			}

			if (_title != null || _caption != null)
			{
				Y += 20;	//标题与下面有一定距离
			}

			if (mCurrentPageIndex == 1 || _top.IsDrawAllPage)
			{
				OutObject(_top);
			}

			if (mCurrentPageIndex == 1 || _header.IsDrawAllPage)
			{
				OutObject(_header);
			}

			if (_title != null || _caption != null || _top.IsDrawAllPage || _header.IsDrawAllPage)
			{
				Y += 5;	//网格与页头距离
			}

			if (mCurrentPageIndex == 1 || _multiHeader.IsDrawAllPage)
			{
				OutObject(_multiHeader);
				
			}

			#region 主体数据网格

			//计算有效高度,便于分页
			float validHeight = printer.PrinterMargins.Height - (Y - printer.PrinterMargins.Top);
			if(_footer != null && _footer.IsDrawAllPage)
			{
				validHeight -= this._footer.Height;
			}
			if(_bottom != null && _bottom.IsDrawAllPage)
			{
				validHeight -= this._bottom.Height;
			}
			if (validHeight < 0)
			{
				throw new Exception("预留给打印主要网格的空间太小,请适当调整!");			
			}

			//有效高度中当前页行数
			int mRowsInCurPage = 0;
			mRowsInCurPage = (int)(validHeight/(float)(this._body.RowHeight));

			//如果指定每页行数,则以其为主
			if (this.RowsPerPage > 0 && this.RowsPerPage < mRowsInCurPage)
			{
				mRowsInCurPage = this.RowsPerPage;
			}

			if (this.IsSubTotalPerPage)
			{
				mRowsInCurPage--;
			}

			//************以Body为主************
			string[,] mArrGridText;			//保留当前页文本,用于页小计
			GoldPrinter.Body mbody;
			
			//如果指定每页行数,则以其为主
			if (this.RowsPerPage > 0 && this.RowsPerPage < mRowsInCurPage)
			{
				mbody = new Body(mRowsInCurPage,this._body.Cols);
			}
			else
			{
				//否则自适应
				if (mRowsInCurPage > (this._body.Rows - this.mCurrentRowIndex))
				{
					mRowsInCurPage = this._body.Rows - this.mCurrentRowIndex;
				}
				mbody = new Body(mRowsInCurPage,this._body.Cols);			
			}
			mbody.ColsAlignString = this._body.ColsAlignString;

			//存当前页的二维文本
			mArrGridText = new string[mRowsInCurPage,this._body.Cols];
			for(int i = 0 ; i < mRowsInCurPage && mCurrentRowIndex < this._body.Rows ; i++)
			{
				for(int j = 0 ; j < this._body.Cols ; j++)
				{
					mArrGridText[i,j] = this._body.GetText(mCurrentRowIndex,j);
				}					
				mCurrentRowIndex++;
			}

			mbody.GridText = mArrGridText;
			OutObject(mbody);					

			//判断是否要分页,只要数据网格行数据大于数据网格行指针,则还有下一页
			if (mCurrentRowIndex < this._body.Rows)
			{
				blnHasMorePage = true;
			}

			#region 打印每页小计,只需要将当前数组用循环累计就OK了,这段程序应专门重构为一个函数,读者可以自己试一试
			if (_isSubTotalPerPage && _subTotalCol != "")
			{
				try
				{
					GoldPrinter.MultiHeader mhSubTotal = new MultiHeader(1,this._body.Cols);
					mhSubTotal.Graphics = g;
					mhSubTotal.PrintDocument = this.mPrintDocument;
					mhSubTotal.Sewing = this._sewing;		

					mhSubTotal.RectangleF = new RectangleF(X,Y,Width,mhSubTotal.Height);		
					//循环
					//....
					mhSubTotal.SetText(0,0,"本页小计");
					mhSubTotal.SetText(0,1,"本页小计");
				
					string[] marrSubTotalCol = this._subTotalCol.Split(';');
					Double mdblSubTotal = 0f;
					int mintCol = 0;

					for(int i = 0 ; i < marrSubTotalCol.Length ; i ++)
					{
						mintCol = int.Parse(marrSubTotalCol[i].Substring(0,1));

						for(int j = 0 ; j < mArrGridText.GetLength(0) ; j++)
						{
							mdblSubTotal += Double.Parse(mArrGridText[j,mintCol]);					
						}
						mhSubTotal.SetText(0,mintCol,mdblSubTotal.ToString());
					}


					mhSubTotal.Draw();			

					Y += mhSubTotal.Height;
				}
				catch(Exception e)
				{}
			}
			#endregion

			#endregion 

			Y += 5;	//网格与页底距离


			//打印页脚与最底
			if (blnHasMorePage == false || _footer.IsDrawAllPage)
			{	
				//这里不再做判断了,读者自己对照Body的处理方法去试验,以加深理解,实际上应是注释的部分
				OutObject(_footer);
				/*
				if (_footer.IsDrawAllPage)
				{
					OutObject(_footer);
				}
				else
				{
					//与Body同样的处理
				}
				*/
			}

			if (blnHasMorePage == false || _bottom.IsDrawAllPage)
			{
				if (_bottom.IsDrawAllPage)
				{
					OutObject(_bottom);
				}
				else
				{
					//计算有效高度
					validHeight = printer.PrinterMargins.Height - (Y - printer.PrinterMargins.Top);
					if (validHeight < _bottom.Height)
					{
						blnHasMorePage = true;
					}
					else
					{
						OutObject(_bottom);
					}
						
				}
			}

			//画边框
			DrawBorder(g,this._multiHeader,mbody);

			mbody = null;

			return blnHasMorePage;
		}
		#endregion

		private void DrawBorder(Graphics g,MultiHeader multiHeader,Body body)
		{
			//网格边框矩阵
			RectangleF mrecGridBorder;
			float x,y,width,height;
			
			width = body.RectangleF.Width;
			height = body.RectangleF.Height;
			if (multiHeader != null)
			{
				x = multiHeader.RectangleF.X;
				y = multiHeader.RectangleF.Y;
				height += multiHeader.RectangleF.Height;
			}
			else
			{
				x = body.RectangleF.X;
				y = body.RectangleF.Y;
			}
			if (this.IsSubTotalPerPage)
			{
				GoldPrinter.MultiHeader m = new MultiHeader(1,1);
				height += m.RowHeight;
				m = null;
			}
			
			mrecGridBorder = new RectangleF(x,y,width,height);
			Pen pen = new Pen(Color.Black,1);

			GoldPrinter.DrawRectangle dr = new DrawRectangle();
			dr.Graphics = g;
			dr.RectangleF = mrecGridBorder;
			dr.Pen = pen;

			switch (GridBorder)
			{
				case GridBorderFlag.Single:
					dr.Draw();
					break;
				case GridBorderFlag.SingleBold:
					dr.Pen.Width = 2;
					dr.Draw();
					if (multiHeader != null)
					{
						dr.RectangleF = body.RectangleF;
						dr.DrawTopLine();
					}
					break;
				case GridBorderFlag.Double:
					dr.Draw();
					mrecGridBorder = new RectangleF(x-2,y-2,width+4,height+4);
					dr.RectangleF = mrecGridBorder;
					dr.Draw();
					break;				
				case GridBorderFlag.DoubleBold:
					dr.Draw();
					mrecGridBorder = new RectangleF(x-2,y-2,width+4,height+4);
					dr.RectangleF = mrecGridBorder;
					dr.Pen.Width = 2;
					dr.Draw();
					break;				
			}
			
		}


		#region 将打印的相关信息输出WriteMetricsToConsole(PrintPageEventArgs ev)
		/*
		public void WriteMetricsToConsole(PrintPageEventArgs ev)
		{
			Graphics g = ev.Graphics;
			Console.WriteLine ("*****Information about the printer*****");
			Console.WriteLine("纸张的大小  ev.PageSettings.PaperSize:" + ev.PageSettings.PaperSize);
			Console.WriteLine("打印分辨率  ev.PageSettings.PrinterResolution:" + ev.PageSettings.PrinterResolution);
			Console.WriteLine("旋转的角度  ev.PageSettings.PrinterSettings.LandscapeAngle" + ev.PageSettings.PrinterSettings.LandscapeAngle);
			Console.WriteLine("");
			Console.WriteLine ("*****Information about the page*****");
			Console.WriteLine("页面的大小  ev.PageSettings.Bounds:" + ev.PageSettings.Bounds); 
			Console.WriteLine("页面(同上)  ev.PageBounds:" + ev.PageBounds); 
			Console.WriteLine("页面的边距    ev.PageSettings.Margins.:" + ev.PageSettings.Margins); 
			Console.WriteLine("页面的边距    ev.MarginBounds:" + ev.MarginBounds); 

			Console.WriteLine("水平分辨率    ev.Graphics.DpiX:" + ev.Graphics.DpiX ); 
			Console.WriteLine("垂直分辨率    ev.Graphics.DpiY:" + ev.Graphics.DpiY ); 

			ev.Graphics.SetClip(ev.PageBounds);
			Console.WriteLine("ev.Graphics.VisibleClipBounds:" + ev.Graphics.VisibleClipBounds);

			SizeF drawingSurfaceSize = new SizeF(
													ev.Graphics.VisibleClipBounds.Width * ev.Graphics.DpiX/100,
													ev.Graphics.VisibleClipBounds.Height * ev.Graphics.DpiY/100);
			Console.WriteLine("drawing Surface Size in Pixels" + drawingSurfaceSize);
		}
		*/
		#endregion

	}//End class
}//End Namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -