四联光电智能照明论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2604|回复: 0
打印 上一主题 下一主题

C# PrintDocument打印 多页 打印预览 

[复制链接]
  • TA的每日心情
    开心
    2022-6-10 09:59
  • 366

    主题

    741

    帖子

    9649

    积分

    超级版主

    Rank: 8Rank: 8

    积分
    9649
    跳转到指定楼层
    楼主
    发表于 2016-10-28 12:53:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    http://www.cnblogs.com/cate-daqi ... /03/23/1992195.html

    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.将事件处理函数添加到PrintDocument的PrintPage事件中。
    docToPrint.PrintPage+=new PrintPageEventHandler(docToPrint_PrintPage);
    4.设置PrintDocument的相关属性,如:
    PrintDialog1.AllowSomePages = truerintDialog1.ShowHelp = true;
    5.把PrintDialog的Document属性设为上面配置好的PrintDocument的实例:
    PrintDialog1.Document = docToPrint;
    6.调用PrintDialog的ShowDialog函数显示打印对话框:
    DialogResult result = PrintDialog1.ShowDialog();
    7.根据用户的选择,开始打印:
    if (result==DialogResult.OK)
       {
        docToPrint.Print();
       }
    8.打印预览控件PrintPreviewDialog
    例子如下:

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

    public partial class PrintTxt
    {
          private   PrintPreviewDialog PrintPreview = new PrintPreviewDialog();
          private   string    StreamType;
          private   Image image = null;
          private   Stream StreamToPrint = null;
          Font mainFont = new Font("宋体", 12);//打印的字体
          public string Filename =null;
            
            
        //1、实例化打印文档
        PrintDocument pdDocument = new PrintDocument();
        private string[] lines;
        private int linesPrinted;


        public PrintTxt(string filepath,string filetype)
        {
             

             Filename = Path.GetFileNameWithoutExtension(filepath);

            //订阅BeginPrint事件
            pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);
            //訂閱EndPrint事件,释放资源
          
             
            pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);


            //订阅Print打印事件,该方法必须放在订阅打印事件的最后
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
            StartPrint(fs, filetype);


            //打印结束
            pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);



        }

        //2、启动Print打印方法
        public   void StartPrint(Stream streamToPrint, string streamType)
        {

            //返回值的PageSettings A4\A5
            PageSettings ps = new PageSettings();
             //显示设置打印页对话框
         PageSetupDialog Psdl = new PageSetupDialog();

            //打印多份设置,注意,该方法需放在printpage方法后面。
         PrintDialog pt = new PrintDialog();
            pt.AllowCurrentPage = true;
            pt.AllowSomePages = true;
            pt.AllowPrintToFile = true;

             StreamToPrint = streamToPrint;//打印的字节流
         StreamType = streamType; //打印的类型
         pdDocument.DocumentName = Filename; //打印的文件名

         Psdl.Document = pdDocument;
            PrintPreview.Document = pdDocument;
            pt.Document = pdDocument;

            Psdl.PageSettings = pdDocument.DefaultPageSettings;
            try
            {
                //显示对话框

                if (Psdl.ShowDialog() == DialogResult.OK)
                {
                    ps = Psdl.PageSettings;
                    pdDocument.DefaultPageSettings = Psdl.PageSettings;
                }

                if (pt.ShowDialog() == DialogResult.OK)
                {
                    pdDocument.PrinterSettings.Copies = pt.PrinterSettings.Copies;
                    pdDocument.Print();
                }
               if(PrintPreview.ShowDialog()==DialogResult.OK )
                //调用打印
                  pdDocument.Print();

                  
                 * PrintDocument对象的Print()方法在PrintController类中执行PrintPage事件。
                 */
            }
            catch (InvalidPrinterException ex)
            {
                MessageBox.Show(ex.Message, "Simple Editor", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }
        }

        /// <summary>
        /// 3、得到打印內容
        /// 每个打印任务只调用OnBeginPrint()一次。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void pdDocument_BeginPrint(object sender, PrintEventArgs e)
        {
            char[] param = { '\n' };
            char[] trimParam = { '\r' };//回车

            switch (StreamType)
            {
                case "txt":
                    StringBuilder text = new StringBuilder();
                    System.IO.StreamReader streamReader = new StreamReader(StreamToPrint, Encoding.Default);
                    while (streamReader.Peek() >= 0)
                    {
                        lines = streamReader.ReadToEnd().Split(param);
                        for (int i = 0; i < lines.Length; i++)
                        {
                            lines = lines.TrimEnd(trimParam);
                        }
                    }

                    break;
                case "image":
                    image = System.Drawing.Image.FromStream(StreamToPrint);
                    break;
                default:
                    break;
            }

        }



        /// <summary>
        /// 4、绘制多个打印界面
        /// printDocument的PrintPage事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnPrintPage(object sender, PrintPageEventArgs e)
        {
            int leftMargin = Convert.ToInt32((e.MarginBounds.Left) * 3 / 4);  //左边距
            int topMargin = Convert.ToInt32(e.MarginBounds.Top * 2 / 3);    //顶边距
            switch (StreamType)
            {
                case "txt":
                    while (linesPrinted < lines.Length)
                    {
                        //向画布中填写内容
                        e.Graphics.DrawString(lines[linesPrinted++], new Font("Arial", 10), Brushes.Black, leftMargin, topMargin, new StringFormat());

                        topMargin += 55;//行高为55,可调整

                        //走纸换页
                        if (topMargin >= e.PageBounds.Height - 60)//页面累加的高度大于页面高度。根据自己需要,可以适当调整
                        {
                            //如果大于设定的高
                            e.HasMorePages = true;

                             /*
                             * PrintPageEventArgs类的HaeMorePages属性为True时,通知控件器,必须再次調用OnPrintPage()方法,打印一个页面。
                             * PrintLoopI()有一个用於每个要打印的页面的序例。如果HasMorePages是False,PrintLoop()就会停止。
                             */
                            return;
                        }
                    }

                    break;
                case "image"://一下涉及剪切图片,
                    int width = image.Width;
                    int height = image.Height;
                    if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height))
                    {
                        width = e.MarginBounds.Width;
                        height = image.Height * e.MarginBounds.Width / image.Width;
                    }
                    else
                    {
                        height = e.MarginBounds.Height;
                        width = image.Width * e.MarginBounds.Height / image.Height;
                    }
                      
                    System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(topMargin, leftMargin, width, height);
                    //向画布写入图片
                    for (int i = 0; i < Convert.ToInt32(Math.Floor((double)image.Height/ 820)) + 1; i++)
                    {
                         
                        e.Graphics.DrawImage(image, destRect, i*820,i*1170 , image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);
                        //走纸换页
                        if (i * 1170 >= e.PageBounds.Height - 60)//页面累加的高度大于页面高度。根据自己需要,可以适当调整
                        {
                            //如果大于设定的高
                            e.HasMorePages = true;

                            /*
                            * PrintPageEventArgs类的HaeMorePages属性为True时,通知控件器,必须再次調用OnPrintPage()方法,打印一个页面。
                            * PrintLoopI()有一个用於每个要打印的页面的序例。如果HasMorePages是False,PrintLoop()就会停止。
                            */
                            return;
                        }
                    }
                  
                    break;
            }

            //打印完毕后,画线条,且注明打印日期
            e.Graphics.DrawLine(new Pen(Color.Black), leftMargin, topMargin, e.MarginBounds.Right, topMargin);

            string strdatetime = DateTime.Now.ToLongDateString() + DateTime.Now.ToLongTimeString();
            e.Graphics.DrawString(string.Format("打印时间:{0}", strdatetime), mainFont, Brushes.Black, e.MarginBounds.Right-240, topMargin+40, new StringFormat());
            linesPrinted = 0;
            //绘制完成后,关闭多页打印功能
            e.HasMorePages = false;

        }


        /// <summary>  
        ///5、EndPrint事件,释放资源
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void pdDocument_EndPrint(object sender, PrintEventArgs e)
        {

            //变量Lines占用和引用的字符串数组,现在释放
            lines = null;
        }
         
    }
    //PrintTxt simple = new PrintTxt("D:\\Mainsoft\\12.txt", "txt");
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|Silian Lighting+ ( 蜀ICP备14004521号-1 )

    GMT+8, 2024-4-28 05:35 , Processed in 1.046875 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表