【转】C#使用PrintDocument打印 多页 打印预览

  PrintDocument实例所有的订阅事件如下:

  1. 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint =     new System.Drawing.Printing.PrintDocument();
  2. 设置打印机开始打印的事件处理函数.函数原形如下 void docToPrint_PrintPage(object sender,     System.Drawing.Printing.PrintPageEventArgs e)
  3. 将事件处理函数添加到PrintDocumentPrintPage事件中 docToPrint.PrintPage+=new PrintPageEventHandler(docToPrint_PrintPage);
  4. 设置PrintDocument的相关属性,如: PrintDialog1.AllowSomePages = true;PrintDialog1.ShowHelp = true;
  5. PrintDialogDocument属性设为上面配置好的PrintDocument的实例 PrintDialog1.Document = docToPrint;
  6. 调用PrintDialogShowDialog函数显示打印对话框 DialogResult result = PrintDialog1.ShowDialog();
  7. 根据用户的选择,开始打印 if (result==DialogResult.OK)    {     docToPrint.Print();    }
  8. 打印预览控件PrintPreviewDialog
  9. PrintPreviewControl 在窗体中添加打印预览

例子如下:

使用时先创建PrintService类的实例,然后调用void StartPrint(Stream streamToPrint,string streamType)函数开始打印。其中streamToPrint是要打印的内容(字节流),streamType是流的类型(txt表示普通文本,image表示图像);

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.IO;  
  6. using System.Drawing.Printing;  
  7. using System.Windows.Forms;  
  8. using System.Drawing;  
  9.   
  10. namespace ConsoleApplication1  
  11. {  
  12.     public partial class PrintTxt:Form  
  13.     {  
  14.   
  15.             
  16.           private   PrintPreviewDialog PrintPreview = new PrintPreviewDialog();  
  17.           private   string    StreamType;  
  18.           private   Image image = null;  
  19.           private   Stream StreamToPrint = null;  
  20.           Font mainFont = new Font("宋体", 12);//打印的字体  
  21.           public string Filename =null;  
  22.             
  23.             
  24.         //1、实例化打印文档  
  25.         PrintDocument pdDocument = new PrintDocument();  
  26.         private string[] lines;  
  27.         private PrintPreviewControl printPreviewControl1;  
  28.   
  29.         public PrintTxt()  
  30.         {  
  31.             InitializeComponent();  
  32.   
  33.         }  
  34.         private int linesPrinted;  
  35.   
  36.   
  37.         public PrintTxt(string filepath,string filetype):this()  
  38.         {  
  39.               
  40.   
  41.              Filename = Path.GetFileNameWithoutExtension(filepath);  
  42.   
  43.             //订阅BeginPrint事件  
  44.             pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);  
  45.             //訂閱EndPrint事件,释放资源  
  46.            
  47.               
  48.             pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);  
  49.   
  50.   
  51.             //订阅Print打印事件,该方法必须放在订阅打印事件的最后  
  52.             FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);  
  53.             StartPrint(fs, filetype);  
  54.   
  55.             
  56.   
  57.             //打印结束  
  58.             pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);  
  59.   
  60.   
  61.   
  62.         }  
  63.   
  64.         //2、启动Print打印方法  
  65.         public   void StartPrint(Stream streamToPrint, string streamType)  
  66.         {  
  67.   
  68.             //声明返回值的PageSettings A4/A5  
  69.             PageSettings ps = new PageSettings();  
  70.   
  71.             //显示设置打印页对话框  
  72.             PageSetupDialog Psdl = new PageSetupDialog();  
  73.   
  74.             //打印多页设置  
  75.             PrintDialog pt = new PrintDialog();  
  76.             pt.AllowCurrentPage = true;  
  77.             pt.AllowSomePages = true;  
  78.             pt.AllowPrintToFile = true;  
  79.   
  80.   
  81.   
  82.   
  83.            
  84.             printPreviewControl1.Document = pdDocument;//form中的打印预览  
  85.             printPreviewControl1.Zoom = 1.0;  
  86.             printPreviewControl1.Dock = DockStyle.Fill;  
  87.             printPreviewControl1.UseAntiAlias = true;  
  88.   
  89.   
  90.             StreamToPrint = streamToPrint;//打印的字节流  
  91.             StreamType = streamType; //打印的类型  
  92.             pdDocument.DocumentName = Filename; //打印的文件名  
  93.   
  94.   
  95.             Psdl.Document = pdDocument;  
  96.             PrintPreview.Document = pdDocument;  
  97.             PrintPreview.SetDesktopLocation(300, 800);  
  98.             Psdl.PageSettings = pdDocument.DefaultPageSettings;  
  99.             pt.Document = pdDocument;  
  100.   
  101.   
  102.   
  103.   
  104.   
  105.             try  
  106.             {  
  107.                 //显示对话框  
  108.   
  109.                 if (Psdl.ShowDialog() == DialogResult.OK)  
  110.                 {  
  111.                     ps = Psdl.PageSettings;  
  112.                     pdDocument.DefaultPageSettings = Psdl.PageSettings;  
  113.                 }  
  114.   
  115.                 if (pt.ShowDialog() == DialogResult.OK)  
  116.                 {  
  117.                     pdDocument.PrinterSettings.Copies = pt.PrinterSettings.Copies;  
  118.                 }  
  119.   
  120.   
  121.                 if (PrintPreview.ShowDialog() == DialogResult.OK)  
  122.                     //调用打印  
  123.                     pdDocument.Print();  
  124.   
  125.                   
  126.                  // PrintDocument对象的Print()方法在PrintController类中执行PrintPage事件。  
  127.                  //  
  128.             }  
  129.             catch (InvalidPrinterException ex)  
  130.             {  
  131.                 MessageBox.Show(ex.Message, "Simple Editor", MessageBoxButtons.OK, MessageBoxIcon.Error);  
  132.                 throw;  
  133.             }  
  134.         }  
  135.   
  136.         /// <summary>  
  137.         /// 3、得到打印內容  
  138.         /// 每个打印任务只调用OnBeginPrint()一次。  
  139.         /// </summary>  
  140.         /// <param name="sender"></param>  
  141.         /// <param name="e"></param>  
  142.         void pdDocument_BeginPrint(object sender, PrintEventArgs e)  
  143.         {  
  144.             char[] param = { '/n' };  
  145.             char[] trimParam = { '/r' };//回车  
  146.   
  147.             switch (StreamType)  
  148.             {  
  149.                 case "txt":  
  150.                     StringBuilder text = new StringBuilder();  
  151.                     System.IO.StreamReader streamReader = new StreamReader(StreamToPrint, Encoding.Default);  
  152.                     while (streamReader.Peek() >= 0)  
  153.                     {  
  154.                         lines = streamReader.ReadToEnd().Split(param);  
  155.                         for (int i = 0; i < lines.Length; i++)  
  156.                         {  
  157.                             lines[i] = lines[i].TrimEnd(trimParam);  
  158.                         }  
  159.                     }  
  160.     
  161.                     break;  
  162.                 case "image":  
  163.                     image = System.Drawing.Image.FromStream(StreamToPrint);  
  164.                     break;  
  165.                 default:  
  166.                     break;  
  167.             }  
  168.   
  169.         }  
  170.   
  171.   
  172.   
  173.         /// <summary>  
  174.         /// 4、绘制多个打印界面  
  175.         /// printDocument的PrintPage事件  
  176.         /// </summary>  
  177.         /// <param name="sender"></param>  
  178.         /// <param name="e"></param>  
  179.         private void OnPrintPage(object sender, PrintPageEventArgs e)  
  180.         {  
  181.             int leftMargin = Convert.ToInt32((e.MarginBounds.Left) * 3 / 4);  //左边距  
  182.             int topMargin = Convert.ToInt32(e.MarginBounds.Top * 2 / 3);    //顶边距  
  183.             switch (StreamType)  
  184.             {  
  185.                 case "txt":  
  186.                     while (linesPrinted < lines.Length)  
  187.                     {  
  188.                         //向画布中填写内容  
  189.                         e.Graphics.DrawString(lines[linesPrinted++], new Font("Arial", 10), Brushes.Black, leftMargin, topMargin, new StringFormat());  
  190.   
  191.                         topMargin += 55;//行高为55,可调整  
  192.   
  193.                         //走纸换页  
  194.                         if (topMargin >= e.PageBounds.Height - 60)//页面累加的高度大于页面高度。根据自己需要,可以适当调整  
  195.                         {  
  196.                             //如果大于设定的高  
  197.                             e.HasMorePages = true;  
  198.                             printPreviewControl1.Rows += 1;//窗体的打印预览窗口页面自动加1  
  199.                              /* 
  200.                              * PrintPageEventArgs类的HaeMorePages属性为True时,通知控件器,必须再次調用OnPrintPage()方法,打印一个页面。 
  201.                              * PrintLoopI()有一个用於每个要打印的页面的序例。如果HasMorePages是False,PrintLoop()就会停止。 
  202.                              */  
  203.                             return;  
  204.                         }  
  205.                     }  
  206.   
  207.                     break;  
  208.                 case "image"://一下涉及剪切图片,  
  209.                     int width = image.Width;  
  210.                     int height = image.Height;  
  211.                     if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height))  
  212.                     {  
  213.                         width = e.MarginBounds.Width;  
  214.                         height = image.Height * e.MarginBounds.Width / image.Width;  
  215.                     }  
  216.                     else  
  217.                     {  
  218.                         height = e.MarginBounds.Height;  
  219.                         width = image.Width * e.MarginBounds.Height / image.Height;  
  220.                     }  
  221.                       
  222.                     System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(topMargin, leftMargin, width, height);  
  223.                     //向画布写入图片  
  224.                     for (int i = 0; i < Convert.ToInt32(Math.Floor((double)image.Height/ 820)) + 1; i++)  
  225.                     {  
  226.                          
  227.                         e.Graphics.DrawImage(image, destRect, i*820,i*1170 , image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);  
  228.                         //走纸换页  
  229.                         if (i * 1170 >= e.PageBounds.Height - 60)//页面累加的高度大于页面高度。根据自己需要,可以适当调整  
  230.                         {  
  231.                             //如果大于设定的高  
  232.                             e.HasMorePages = true;  
  233.                             printPreviewControl1.Rows += 1;//窗体的打印预览窗口页面自动加1  
  234.                             /* 
  235.                             * PrintPageEventArgs类的HaeMorePages属性为True时,通知控件器,必须再次調用OnPrintPage()方法,打印一个页面。 
  236.                             * PrintLoopI()有一个用於每个要打印的页面的序例。如果HasMorePages是False,PrintLoop()就会停止。 
  237.                             */  
  238.                             return;  
  239.                         }  
  240.                     }  
  241.                   
  242.                     break;  
  243.             }  
  244.   
  245.             //打印完毕后,画线条,且注明打印日期  
  246.             e.Graphics.DrawLine(new Pen(Color.Black), leftMargin, topMargin, e.MarginBounds.Right, topMargin);   
  247.   
  248.             string strdatetime = DateTime.Now.ToLongDateString() + DateTime.Now.ToLongTimeString();  
  249.             e.Graphics.DrawString(string.Format("打印时间:{0}", strdatetime), mainFont, Brushes.Black, e.MarginBounds.Right-240, topMargin+40, new StringFormat());  
  250.             linesPrinted = 0;  
  251.             //绘制完成后,关闭多页打印功能  
  252.             e.HasMorePages = false;  
  253.   
  254.         }  
  255.   
  256.   
  257.         /// <summary>    
  258.         ///5、EndPrint事件,释放资源  
  259.         /// </summary>  
  260.         /// <param name="sender"></param>  
  261.         /// <param name="e"></param>  
  262.         void pdDocument_EndPrint(object sender, PrintEventArgs e)  
  263.         {  
  264.   
  265.             //变量Lines占用和引用的字符串数组,现在释放  
  266.             lines = null;  
  267.         }  
  268.   
  269.         private void InitializeComponent()  
  270.         {  
  271.             this.printPreviewControl1 = new System.Windows.Forms.PrintPreviewControl();  
  272.             this.SuspendLayout();  
  273.             //   
  274.             // printPreviewControl1  
  275.             //   
  276.             this.printPreviewControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)  
  277.                         | System.Windows.Forms.AnchorStyles.Left)  
  278.                         | System.Windows.Forms.AnchorStyles.Right)));  
  279.             this.printPreviewControl1.Location = new System.Drawing.Point(12, 3);  
  280.             this.printPreviewControl1.Name = "printPreviewControl1";  
  281.             this.printPreviewControl1.Size = new System.Drawing.Size(685, 511);  
  282.             this.printPreviewControl1.TabIndex = 0;  
  283.             //   
  284.             // PrintTxt  
  285.             //   
  286.             this.ClientSize = new System.Drawing.Size(696, 526);  
  287.             this.Controls.Add(this.printPreviewControl1);  
  288.             this.Name = "PrintTxt";  
  289.             this.ResumeLayout(false);  
  290.   
  291.         }  
  292.          
  293.     }  
  294.     //PrintTxt simple = new PrintTxt("D://Mainsoft//12.txt", "txt");   
  295. }  

 

 

调用方式 PrintTxt simple = new PrintTxt("D://Mainsoft//12.txt", "txt");

验证通过; 

posted @ 2013-11-05 16:47  summer0311  阅读(5773)  评论(0编辑  收藏  举报