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);
param name
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;
}
}
}
后记:其实在调打印机的过程中会遇到很多问题,这些更多的是要对打印机相对的熟悉。很多时候不是程序的问题,⽽是打印机的设置、驱动造成的。---为⽑要有那么多不同型号、不同驱动的打印机呢

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。