C#程序中实现打印功能

最近在弄C#调用打印机批量打印rdlc报表的功能,以下就定义的一个打印机帮助类。

说明:1、设置默认打印机的API,主要是用于外部调用

2、打印中遇到了很多问题,不同的打印机有时会出现各种各样的问题(曾想通过API去调用打印实现,最终技术没达标…),主要产生的原因是系统本身,更多的是打印机以及驱动的问题。例如在获取默认打印机的时候总是报出“未设置默认打印机。”的提示,更多时是打印机驱动没有安装好造成的。而遇到针式打印机可以打印,激光打印机却不能打印的问题,暂未解决。

3、此帮助类基本上可以完成程序调用打印功能,关于打印机状态等信息(略)。

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;

namespace SymbolTestPlatform.TestWin
{

    public class PrinterHelper
    {
        [DllImport("winspool.drv")]
        public static extern bool SetDefaultPrinter(String Name); //调用win api将指定名称的打印机设置为默认打印机
        int currentPageIndex;
        IList<Stream> listStream;
        private static MemoryStream reportDefinition = null;

        public delegate void EndPrintHandler(object sender);
        public event EndPrintHandler EndPrint;

        public PrinterHelper()
        {
            List<string> lst = new List<string>();
        }

        /// <summary>
        /// 设定报表模板、绑定数据,准备打印
        /// </summary>
        /// <param name="dtinvoice"></param>
        /// <param name="strConfigPath"></param>
        /// <param name="reportPath"></param>
        /// <param name="printerName"></param>
        /// <param name="param"></param>
        public void Print(DataTable dtinvoice, string strConfigPath, string reportPath, string printerName, ReportParameter[] param)
        {
            if (string.IsNullOrEmpty(reportPath))
            {
                MessageBox.Show("报表模板不能为空");
                return;
            }
            reportDefinition = new MemoryStream(File.ReadAllBytes(reportPath), false); ;
            LocalReport report = new LocalReport();
            report.LoadReportDefinition(reportDefinition);

            if (param != null)
                report.SetParameters(param);
            report.DataSources.Add(new ReportDataSource("DataSet1", dtinvoice));
            Print(report, printerName, strConfigPath);
        }

        /// <summary>
        /// 将报表渲染成stream
        /// </summary>
        /// <param name="report"></param>
        /// <param name="strConfigPath"></param>
        private void Export(LocalReport report, string strConfigPath)
        {
            try
            {
                string deviceInfo = "";
                using (FileStream fs = new FileStream(strConfigPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                using (StreamReader sr = new StreamReader(fs))
                    deviceInfo = sr.ReadToEnd();

                Warning[] warnings;
                if (listStream != null) foreach (var i in listStream) i.Close();
                listStream = new List<Stream>();
                report.Render("Image", deviceInfo, CreateStream, out warnings);
                foreach (var i in listStream) i.Position = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("处理报表产生错误:{0}", ex.Message), "操作提示");
            }
        }
        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="report"></param>
        /// <param name="printerName"></param>
        /// <param name="strConfigPath"></param>
        private void Print(LocalReport report, string printerName, string strConfigPath)
        {
            Export(report, strConfigPath);
            if (listStream == null || listStream.Count <= 0) return;
            PrintDocument pd = new PrintDocument();
            pd.PrintController = new StandardPrintController();
            if (PrinterSettings.InstalledPrinters.Count <= 0)
            {
                MessageBox.Show("该计算机没有任何打印机,请先安装打印机", "系统提示");
                return;
            }
            if (!string.IsNullOrEmpty(printerName))
            {
                pd.PrinterSettings.PrinterName = printerName;
            }
            //有时PrinterSettings.IsValid始终返回false,错误原因更多的因该是打印机安装以及驱动问题
            if (!pd.PrinterSettings.IsValid)
            {
                //throw new Exception(string.Format("无法找到名称为 {0} 的打印机", printerName));
                MessageBox.Show(string.Format("无法找到名称为 {0} 的打印机", pd.PrinterSettings.PrinterName), "系统提示");
                return;
            }
            //定义打印格式大小
            System.Drawing.Printing.PageSettings df = new System.Drawing.Printing.PageSettings();
            //df.PaperSize = new PaperSize("nn", 709, 417);
            df.PaperSize = new PaperSize()
            {
                Height = 393,
                Width = 669,
            };
            df.Margins = new Margins(40, 40, 20, 0);
            pd.DefaultPageSettings = df;
            pd.DefaultPageSettings.Landscape = false;

            pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
            pd.EndPrint += new PrintEventHandler(pd_EndPrint);
            currentPageIndex = 0;

            try
            {
                pd.Print();   //打印
            }
            catch (Exception e)
            {
                OnEndPrint();
                throw;
            }

        }
        /// <summary>
        /// 回调函数
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fileNameExtension"></param>
        /// <param name="encoding"></param>
        /// <param name="mimeType"></param>
        /// <param name="willSeek"></param>
        /// <returns></returns>
        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            Stream s = new MemoryStream();
            listStream.Add(s);
            return s;
        }
        /// <summary>
        /// 打印页面操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pd_PrintPage(object sender, PrintPageEventArgs e)
        {
            Metafile pageImage = new Metafile(listStream[currentPageIndex]);
            e.Graphics.Clear(System.Drawing.Color.White);
            e.Graphics.DrawImage(pageImage, e.PageBounds);
            e.Graphics.Flush();

            currentPageIndex++;
            e.HasMorePages = currentPageIndex < listStream.Count;
        }

        /// <summary>
        /// 打印结束
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private  void pd_EndPrint(object sender, PrintEventArgs e)
        {
            OnEndPrint();
        }

      
        private void OnEndPrint()
        {
            if (EndPrint != null) EndPrint(this);
            if (listStream != null) foreach (var i in listStream) i.Close();
        }

        public void Dispose()
        {
            if (listStream != null) foreach (var i in listStream) i.Close();
            listStream = null;
        }
    }
}

 

 

 

后记:其实在调打印机的过程中会遇到很多问题,这些更多的是要对打印机相对的熟悉。很多时候不是程序的问题,而是打印机的设置、驱动造成的。尼玛---为毛要有那么多不同型号、不同驱动的打印机呢

posted @ 2014-11-14 00:42  Tim_et  阅读(1041)  评论(0)    收藏  举报