o任飘零o

别人给了你一滴水,你给了别人些什么?
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、封装CustomPrintController类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;

namespace PrinterTest
{
    /// <summary>
    /// 打印控制
    /// </summary>
    public class CustomPrintController : PreviewPrintController
    {
        #region 变量/属性

        #region EnmPrintType
        /// <summary>
        /// 打印模式枚举【全部、奇数页、偶数页、指定页等】
        /// </summary>
        public enum EnmPrintType
        {
            All,
            Odd,
            Even,
            Range,
            PageNumber
        }
        #endregion

        #region 页面列表
        /// <summary>
        /// 页面列表
        /// </summary>
        private List<Metafile> _lstMetafile = new List<Metafile>();
        #endregion

        #region 打印页码列表
        /// <summary>
        /// 打印页码列表
        /// </summary>
        private List<int> _lstPrintPageNumber = new List<int>();
        #endregion

        #region 当前正在打印页码索引
        /// <summary>
        /// 当前正在打印页码索引
        /// </summary>
        private int _intCurrentPrintPageIndex = -1;
        #endregion

        #region 获取总页数
        /// <summary>
        /// 获取总页数
        /// </summary>
        private int PageCount
        {
            get 
            {
                if (this._lstMetafile == null)
                {
                    return 0;
                }
                return this._lstMetafile.Count;
            }
        }
        #endregion

        #endregion

        #region OnStartPrint
        /// <summary>
        /// OnStartPrint
        /// </summary>
        /// <param name="document"></param>
        /// <param name="e"></param>
        public override void OnStartPrint(PrintDocument document, PrintEventArgs e)
        {
            base.OnStartPrint(document, e);
            this._lstMetafile.Clear();
        }
        #endregion

        #region OnEndPage
        /// <summary>
        /// OnEndPage
        /// </summary>
        /// <param name="document"></param>
        /// <param name="e"></param>
        public override void OnEndPage(PrintDocument document, PrintPageEventArgs e)
        {
            base.OnEndPage(document, e);
            PreviewPageInfo[] ppia = GetPreviewPageInfo();
            PreviewPageInfo ppi = ppia[ppia.Length - 1];
            Metafile _Metafile = (Metafile)ppi.Image;
            this._lstMetafile.Add(_Metafile);
        }
        #endregion

        #region PrintPage
        /// <summary>
        /// PrintPage
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrintPage(object sender, PrintPageEventArgs e)
        {
            if (this._lstMetafile == null || this.PageCount == 0)
            {
                return;
            }
            ++this._intCurrentPrintPageIndex;

            //打印当前页
            int intPrintPageIndex = this._intCurrentPrintPageIndex;
            if (intPrintPageIndex < 0 || intPrintPageIndex > this._lstPrintPageNumber.Count - 1)
            {
                return;
            }
            int intMetafileIndex = _lstPrintPageNumber[intPrintPageIndex] - 1;
            if (intMetafileIndex < 0 || intMetafileIndex > this.PageCount - 1)
            {
                return;
            }
            e.Graphics.DrawImage(this._lstMetafile[intMetafileIndex], new Rectangle(0, 0, e.PageSettings.PaperSize.Width, e.PageSettings.PaperSize.Height));
           
            //验证下一页是否能打印
            int intNextPrintPageIndex = this._intCurrentPrintPageIndex + 1;
            if (intNextPrintPageIndex < 0 || intNextPrintPageIndex > this._lstPrintPageNumber.Count - 1)
            {
                return;
            }
            int intNextMetafileIndex = _lstPrintPageNumber[intNextPrintPageIndex] - 1;
            if (intNextPrintPageIndex < 0 || intNextPrintPageIndex > this.PageCount - 1)
            {
                return;
            }
            e.HasMorePages = true;
        }
        #endregion

        #region Print
        /// <summary>
        /// Print
        /// </summary>
        /// <param name="p_enmPrintType">打印模式</param>
        /// <param name="p_intPrintPageNumber">p_enmPrintType=EnmPrintType.Page有效</param>
        /// <param name="p_strPrintRange">p_enmPrintType=EnmPrintType.Range有效  分隔符: ,- </param>
        /// <returns></returns>
        private void Print(EnmPrintType p_enmPrintType, int p_intPrintPageNumber, string p_strPrintRange)
        {
            if(!m_blnSetPrintPageNumber(p_enmPrintType, p_intPrintPageNumber, p_strPrintRange))
            {
                return;
            }

            System.Drawing.Printing.PrintDocument objDoc = null;
            try
            {
                objDoc = new System.Drawing.Printing.PrintDocument();
                this._intCurrentPrintPageIndex = -1;
                objDoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.PrintPage);
                objDoc.Print();
            }
            catch (Exception objEx)
            {
                MessageBox.Show("打印出错。\r\n\r\n" + objEx.Message);
            }
            finally
            {
                if (objDoc != null)
                {
                    objDoc.Dispose();
                    objDoc = null;
                }
            }
        }
        #endregion

        #region 设置打印页码列表
        /// <summary>
        /// 设置打印页码列表
        /// </summary>
        /// <param name="p_enmPrintType">打印模式</param>
        /// <param name="p_intPrintPageNumber">p_enmPrintType=EnmPrintType.Page有效</param>
        /// <param name="p_strPrintRange">p_enmPrintType=EnmPrintType.Range有效</param>
        /// <returns></returns>
        private bool m_blnSetPrintPageNumber(EnmPrintType p_enmPrintType, int p_intPrintPageNumber, string p_strPrintRange)
        {
            this._lstPrintPageNumber.Clear();

            switch (p_enmPrintType)
            {
                case EnmPrintType.All:
                    for (int i1 = 0; i1 < this.PageCount; i1++)
                    {
                        int intPageNumber = i1 + 1;
                        this._lstPrintPageNumber.Add(intPageNumber);
                    }
                    break;
                case EnmPrintType.Odd:
                    for (int i1 = 0; i1 < this.PageCount; i1++)
                    {
                        int intPageNumber = i1 + 1;
                        if (intPageNumber % 2 != 0)
                        {
                            this._lstPrintPageNumber.Add(intPageNumber);
                        }
                    }
                    break;
                case EnmPrintType.Even:
                    for (int i1 = 0; i1 < this.PageCount; i1++)
                    {
                        int intPageNumber = i1 + 1;
                        if (intPageNumber % 2 == 0)
                        {
                            this._lstPrintPageNumber.Add(intPageNumber);
                        }
                    }
                    break;
                case EnmPrintType.Range:
                    #region 解析打印范围
                    string strRangeText = p_strPrintRange;
                    if (strRangeText == null)
                    {
                        this._lstPrintPageNumber.Clear();
                        return false;
                    }
                    string[] strArr = strRangeText.Split(new char[] { ',', '' }, StringSplitOptions.RemoveEmptyEntries);
                    if (strArr == null)
                    {
                        this._lstPrintPageNumber.Clear();
                        return false;
                    }
                    for (int i1 = 0; i1 < strArr.Length; i1++)
                    {
                        string str = strArr[i1];
                        if (!str.Trim().Contains('-'))
                        {
                            try
                            {
                                int intPageNumber = Convert.ToInt32(str.Trim());
                                if (intPageNumber > 0 && intPageNumber < this.PageCount)
                                {
                                    this._lstPrintPageNumber.Add(intPageNumber);
                                }
                            }
                            catch
                            {
                                MessageBox.Show("输入打印范围的格式有误。");
                                this._lstPrintPageNumber.Clear();
                                return false;
                            }
                        }
                        else
                        {
                            string[] strArr2 = str.Trim().Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                            if (strArr2.Length > 1)
                            {
                                try
                                {
                                    int intFromPage = Convert.ToInt32(strArr2[0]);
                                    int intToPage = Convert.ToInt32(strArr2[strArr2.Length - 1]);
                                    for (int page = intFromPage; page <= intToPage; page++)
                                    {
                                        if (page > 0 && page < this.PageCount)
                                        {
                                            this._lstPrintPageNumber.Add(page);
                                        }
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("输入打印范围的格式有误。");
                                    this._lstPrintPageNumber.Clear();
                                    return false;
                                }
                            }
                            else
                            {
                                MessageBox.Show("输入打印范围的格式有误。");
                                this._lstPrintPageNumber.Clear();
                                return false;
                            }
                        }
                    }
                    #endregion
                    break;
                case EnmPrintType.PageNumber:
                    if (p_intPrintPageNumber > 0 && p_intPrintPageNumber < this.PageCount)
                    {
                        this._lstPrintPageNumber.Add(p_intPrintPageNumber);
                    }
                    break;
            }
            if (this._lstPrintPageNumber.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 打印
        /// <summary>
        /// 打印全部
        /// </summary>
        public void PrintAll()
        {
            Print(EnmPrintType.All, 0, null);
        }
        /// <summary>
        /// 打印奇数页
        /// </summary>
        public void PrintOdd()
        {
            Print(EnmPrintType.Odd, 0, null);
        }
        /// <summary>
        /// 打印偶数页
        /// </summary>
        public void PrintEven()
        {
            Print(EnmPrintType.Even, 0, null);
        }
        /// <summary>
        /// 打印指定范围页
        /// </summary>
        /// <param name="p_strPrintRange">指定范围 分隔符: ,- </param>
        public void PrintRange(string p_strPrintRange)
        {
            Print(EnmPrintType.Range, 0, p_strPrintRange);
        }
        /// <summary>
        /// 打印指定页
        /// </summary>
        /// <param name="p_intPageNumber">指定页码</param>
        public void PrintPageNumber(int p_intPageNumber)
        {
            Print(EnmPrintType.PageNumber, p_intPageNumber, null);
        }
        #endregion
    }
}


二、使用CustomPrintController类进行打印控制,该类的使用方法以下:

2.1)添加 System.Drawing.Printing.PrintDocument控件(如控件名为:_pDoc),并实现该控件的下面三个事件(注:该三个事件类似全部打印一要,该怎么打印就怎么打印,该怎么分页就怎么分页,不需要考虑奇偶打印、指定页打印等等):
this._pDoc.BeginPrint += new System.Drawing.Printing.PrintEventHandler(this._pDoc_BeginPrint);
this._pDoc.EndPrint += new System.Drawing.Printing.PrintEventHandler(this._pDoc_EndPrint);
this._pDoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this._pDoc_PrintPage);

2.2)在窗体Load事件中添加以下代码:

CustomPrintController objPrintController = new CustomPrintController();             
_pDoc.PrintController = objPrintController;

 

2.3)在第2.4点操作之前保证添加 的System.Drawing.Printing.PrintDocument控件执行一次Print方法,如在窗体的Load事件中(具体考虑效率放在哪更有效):

this._pDoc.Print();

    注:之所以要执行Print方法,是为了让CustomPrintController类中的事件OnEndPage执行,以便计算出生成的所有页面列表。

2.4)“打印”按钮点击事件:

private void btnPrint_Click(object sender, EventArgs e)
        {
            CustomPrintController objPrintController = _pDoc.PrintController as CustomPrintController;
            if (objPrintController != null)
            {
                if (rdbOdd.Checked)
                {//打印奇数页
                    objPrintController.PrintOdd();
                }
                else if (rdbEven.Checked)
                {//打印偶数页
                    objPrintController.PrintEven();
                }
                else if (rdbRange.Checked)
                {//打印范围
                    objPrintController.PrintRange(txtRange.Text.Trim());
                }
                else if (rdbPageNumber.Checked)
                {//打印指定页
                    int intPageNumber = 0;
                    int.TryParse(txtPageNumber.Text.Trim(), out intPageNumber);
                    objPrintController.PrintPageNumber(intPageNumber);
                }
                else
                {//打印全部
                    objPrintController.PrintAll();
                }
            }
        }