职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 1486|回复: 2

在 C# 中实现打印功能

[复制链接]
joe 发表于 2007-2-27 19:35 | 显示全部楼层 |阅读模式
在C#中使用PrintDialog可以很方便的实现程序的打印功能。

    其步骤如下:

    创建一个PrintDialog的实例。如下:
  1. System.Windows.Forms.PrintDialog PrintDialog1=new PrintDialog ();
复制代码
创建一个PrintDocument的实例.如下:
  1.     System.Drawing.Printing.PrintDocument docToPrint =
  2.     new System.Drawing.Printing.PrintDocument();
复制代码
设置打印机开始打印的事件处理函数.函数原形如下:
  1.     void docToPrint_PrintPage(object sender,
  2.     System.Drawing.Printing.PrintPageEventArgs e)
复制代码
将事件处理函数添加到PrintDocument的PrintPage事件中。
  1. docToPrint.PrintPage+=new PrintPageEventHandler(docToPrint_PrintPage);
复制代码
设置PrintDocument的相关属性,如:
  1. PrintDialog1.AllowSomePages = true;PrintDialog1.ShowHelp = true;
复制代码
把PrintDialog的Document属性设为上面配置好的PrintDocument的实例:
  1. PrintDialog1.Document = docToPrint;
复制代码
调用PrintDialog的ShowDialog函数显示打印对话框:
  1. DialogResult result = PrintDialog1.ShowDialog();
复制代码
根据用户的选择,开始打印:
  1.     if (result==DialogResult.OK)
  2.     {
  3.     docToPrint.Print();
  4.     }
复制代码
例子如下:

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

  5.     namespace EDImageSystem
  6.     {
  7.     /// 〈summary〉
  8.     /// PrintService 的摘要说明。
  9.     /// 〈/summary〉
  10.     public class PrintService
  11.     {
  12.     public PrintService()
  13.     {
  14.     //
  15.     // TODO: 在此处添加构造函数逻辑
  16.     //
  17.     this.docToPrint.PrintPage+=new PrintPageEventHandler(docToPrint_PrintPage);
  18.     }//将事件处理函数添加到PrintDocument的PrintPage中

  19.     // Declare the PrintDocument object.
  20.     private System.Drawing.Printing.PrintDocument docToPrint =
  21.     new System.Drawing.Printing.PrintDocument();//创建一个PrintDocument的实例

  22.     private System.IO.Stream streamToPrint;
  23.     string streamType;

  24.     // This method will set properties on the PrintDialog object and
  25.     // then display the dialog.
  26.     public void StartPrint(Stream streamToPrint,string streamType)
  27.     {

  28.     this.streamToPrint=streamToPrint;
  29.     this.streamType=streamType;
  30.     // Allow the user to choose the page range he or she would
  31.     // like to print.
  32.     System.Windows.Forms.PrintDialog PrintDialog1=new PrintDialog ();//创建一个PrintDialog的实例。
  33.     PrintDialog1.AllowSomePages = true;

  34.     // Show the help button.
  35.     PrintDialog1.ShowHelp = true;

  36.     // Set the Document property to the PrintDocument for
  37.     // which the PrintPage Event has been handled. To display the
  38.     // dialog, either this property or the PrinterSettings property
  39.     // must be set
  40.     PrintDialog1.Document = docToPrint;//把PrintDialog的Document属性设为上面配置好的PrintDocument的实例

  41.     DialogResult result = PrintDialog1.ShowDialog();//调用PrintDialog的ShowDialog函数显示打印对话框

  42.     // If the result is OK then print the document.
  43.     if (result==DialogResult.OK)
  44.     {
  45.     docToPrint.Print();//开始打印
  46.     }

  47.     }

  48.     // The PrintDialog will print the document
  49.     // by handling the document’s PrintPage event.
  50.     private void docToPrint_PrintPage(object sender,
  51.     System.Drawing.Printing.PrintPageEventArgs e)//设置打印机开始打印的事件处理函数
  52.     {

  53.     // Insert code to render the page here.
  54.     // This code will be called when the control is drawn.

  55.     // The following code will render a simple
  56.     // message on the printed document
  57.     switch(this.streamType)
  58.     {
  59.     case “txt“:
  60.     string text = null;
  61.     System.Drawing.Font printFont = new System.Drawing.Font
  62.     (“Arial“, 35, System.Drawing.FontStyle.Regular);

  63.     // Draw the content.
  64.     System.IO.StreamReader streamReader=new StreamReader(this.streamToPrint);
  65.     text=streamReader.ReadToEnd();
  66.     e.Graphics.DrawString(text,printFont,System.Drawing.Brushes.Black,e.MarginBounds.X,e.MarginBounds.Y);
  67.     break;
  68.     case “image“:
  69.     System.Drawing.Image image=System.Drawing.Image.FromStream(this.streamToPrint);
  70.     int x=e.MarginBounds.X;
  71.     int y=e.MarginBounds.Y;
  72.     int width=image.Width;
  73.     int height=image.Height;
  74.     if((width/e.MarginBounds.Width)〉(height/e.MarginBounds.Height))
  75.     {
  76.     width=e.MarginBounds.Width;
  77.     height=image.Height*e.MarginBounds.Width/image.Width;
  78.     }
  79.     else
  80.     {
  81.     height=e.MarginBounds.Height;
  82.     width=image.Width*e.MarginBounds.Height/image.Height;
  83.     }
  84.     System.Drawing.Rectangle destRect=new System.Drawing.Rectangle(x,y,width,height);
  85.     e.Graphics.DrawImage(image,destRect,0,0,image.Width,image.Height,System.Drawing.GraphicsUnit.Pixel);
  86.     break;
  87.     default:
  88.     break;
  89.     }

  90.     }

  91.     }
  92.     }
复制代码
 楼主| joe 发表于 2007-2-27 19:35 | 显示全部楼层
用 C# 实现完整文档打印功能

    在 windows 应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .net Framework的打
    印功能都以组件的方式提供,为程序员提供了很大的方便,但是这几个组件的使用还是很复杂的,有必要解释一下。

    打印操作通常包括以下四个功能
    1 打印设置 设置打印机的一些参数比如更改打印机驱动程序等
    2 页面设置 设置页面大小纸张类型等
    3 打印预览 类似于word中的打印预览
    4 打印

    下面我把我编写的记事本(全部源代码可以在http://www.cndot.net中下载)中用到的打印功能的代码进行解释希望能给大家一些帮助
    实现打印功能的核心是PrintDocument类这个类属于System.Drawing.Printing名字空间这个类封装了当前的打印设置页面设置以及所
    有的与打印有关的事件和方法
    这个类包括以下几个属性 事件 和方法
    1、PrinterSettings 属性
      存放打印机的设置信息这个属性不需要程序员设置因为它是由打印对话框获取的
    2、PrintCountroller 属性
      控制打印过程
    3、DefaultPageSettings 属性
      存放页面设置信息 打印纸大小方向等也不需要程序员设置因为它是由页面设置对话框获取的
    4、DocumentName 属性

    指定文档名称,出现在打印机状态窗口中
    1。 BeginPrint事件
      在打印之前发出
    2. PrintPage事件
      每打印一页是发出,事件接受一个PrintPageEventArgs参数该参数封装了打印相关的信息
      PrintPageEventArgs参数有很多重要的属性
      1 Cancel 取消打印
      2 Graphics 页面的绘图对象
      3 HasMorePages 是否还有要打印的页面
    Print 方法 该方法没有参数 调用它将按照当前设置开始打印
    若实现打印功能首先构造PrintDocument对象添加打印事件
    PrintDocument printDocument;
    private void InitializeComponent()
    {
    ...
    printDocument=new PrintDocument();
    printDocument.PrintPage += new PrintPageEventHandler (this.printDocument_PrintPage);
    ...
    }
    实现打印事件功能
    打印和绘图类似都是调用Graphics 类的方法进行画图 不同的是一个在显示器上一个在打印纸上并且打印要进行一些复杂的计算
    如换行 分页等。
    private void printDocument_PrintPage(object sender,PrintPageEventArgs e)
    {
    Graphics g = e.Graphics; //获得绘图对象
    float linesPerPage = 0; //页面的行号
    float yPosition = 0;   //绘制字符串的纵向位置
    int count = 0; //行计数器
    float leftMargin = e.MarginBounds.Left; //左边距
    float topMargin = e.MarginBounds.Top; //上边距
    string line = null; 行字符串
    Font printFont = this.textBox.Font; //当前的打印字体
    SolidBrush myBrush = new SolidBrush(Color.Black);//刷子
    linesPerPage = e.MarginBounds.Height / printFont.GetHeight(g);//每页可打印的行数
    //逐行的循环打印一页
        while(count 〈 linesPerPage && ((line=lineReader.ReadLine()) != null))
        {
           yPosition = topMargin + (count * printFont.GetHeight(g));
           g.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());
           count++;
        }
    如果本页打印完成而line不为空说明还有没完成的页面这将触发下一次的打印事件在下一次的打印中lineReader会
    自动读取上次没有打印完的内容因为lineReader是这个打印方法外的类的成员它可以记录当前读取的位置
        if(line != null)
            e.HasMorePages = true;
        else
            e.HasMorePages = false;
    }
    打印设置,构造打印对话框 将对话框中设置的Document属性赋给printDocument这样会将用户的设置自动保存到printDocument
    的PrinterSettings属性中
    protected  void FileMenuItem_PrintSet_Click(object sender,EventArgs e)
    {
    PrintDialog printDialog = new PrintDialog();
    printDialog.Document = printDocument;
    printDialog.ShowDialog();
    }
    页面设置和打印预览与打印设置原理相同都是构造对话框将用户在对话框中的设置保存到相应的类的属性中
    protected  void FileMenuItem_PageSet_Click(object sender,EventArgs e)
    {
      PageSetupDialog pageSetupDialog = new PageSetupDialog();
      pageSetupDialog.Document = printDocument;
      pageSetupDialog.ShowDialog();
    }
    打印预览
    protected void FileMenuItem_PrintView_Click(object sender,EventArgs e)
    {
       PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
       printPreviewDialog.Document = printDocument;
       lineReader = new StringReader(textBox.Text);
       try
          {
        printPreviewDialog.ShowDialog();
          }
        catch(Exception excep)
        {
        MessageBox.Show(excep.Message, “打印出错“, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    打印就可以直接调用printDocument的Print()方法因为用户可能在打印之前还要再更改打印设置所以
    在这里再次显示打印设置对话框
      protected void FileMenuItem_Print_Click(object sender,EventArgs e)
      {
       PrintDialog printDialog = new PrintDialog();
       printDialog.Document = printDocument;
       lineReader = new StringReader(textBox.Text);
       if (printDialog.ShowDialog() == DialogResult.OK)
       {
        try
           {
           printDocument.Print();
           }
           catch(Exception excep)
                {
                  MessageBox.Show(excep.Message, “打印出错“, MessageBoxButtons.OK, MessageBoxIcon.Error);
                  printDocument.PrintController.OnEndPrint(printDocument,new PrintEventArgs());
                }
           }
      }
    总结打印的过程是
    1 在应用程序窗体初始化时构造PrintDocument对象  添加 printDocument 的 PrintPage 方法
    2 实现PrintPage方法  4 在用户的单击事件中调用 printDocument 的 Print方法实现打印功能在这中间可能要用到  PrintDialog PrintPreviewDialog PageSetupDialog 设置和查看打印效果这些方法通常是由菜单的单击触发的。
 楼主| joe 发表于 2007-2-27 19:36 | 显示全部楼层
C# 枚举系统安装的所有打印机

    最近在论坛中不少网友问“如何把Windows安装的所有打印机列出来“,在下面的程序中我们将把系统中所安装的打印机用列表框列出来,同时为默认打印机设置缺省值。

  在下面的程序中我们用到了两个主要的类,把所有的打印机列表出来用到了PrinterSettings 类,获取系统默认打印机用到了PrintDocument 类,下面我们就动手实践一下吧。

  先新建一个windows form的工程,然后加入一个lable和一个comBox,就行啦,关键在下面啦,我们如何获得默认打印机,就得用下面的语句。

PrintDocument prtdoc = new PrintDocument();
string strDefaultPrinter = prtdoc.PrinterSettings.PrinterName;//获取默认的打印机名

  有了默认的打印机,我们再把所有的打印机列出来。

  PrinterSettings类有一个InstalledPrinters的属性,不知是做什么的吧,查MSDN如下解释:
PrinterSettings.InstalledPrinters 获取安装在计算机上所有打印机的名称。

  在C#中如下定义:

[C#]
[Serializable]
[ComVisible(false)]
public static PrinterSettings.StringCollection InstalledPrinters
{get;}

  属性值

  PrinterSettings.StringCollection,它表示安装在计算机上所有打印机的名称。

  异常

异常类型 条件
Win32Exception 未能枚举可用的打印机

  备注

  可以使用已安装的打印机名称的集合向用户提供要打印到的打印机选择。

  下面的示例用已安装的打印机填充 comboInstalledPrinters 组合框,并且还在选择更改时使用 PrinterName 属性设置用于打印的打印机。PopulateInstalledPrintersCombo 例程在窗体初始化时被调用。该示例假定存在名为 printDoc 的 PrintDocument 变量,并且存在特定的组合框。

[C#]
//下面括号内的自己翻译添加进去的
private void PopulateInstalledPrintersCombo()
{
// Add list of installed printers found to the combo box.(将系统中所有的打机加入列表框)
// The pkInstalledPrinters string will be used to provide the display string.(列表框中显示的字串由pkInstalledPrinters提供)
foreach(String pkInstalledPrinters in
PrinterSettings.InstalledPrinters)
{
comboInstalledPrinters.Items.Add(pkInstalledPrinters);
}
}

private void comboInstalledPrinters_SelectionChanged(object sender, System.EventArgs e)
{

// Set the printer to a printer in the combo box when the selection changes.(当列表框改变时设置选择的打印机)

if (comboInstalledPrinters.SelectedIndex != -1)
{
// The combo box’’s Text property returns the selected item’’s text, which is the printer name.(将选择的打印机名在列表框中显示)
printDoc.PrinterSettings.PrinterName= comboInstalledPrinters.Text;
}

}

  看了MSDN的说明,懂多了吧,下面是我写练习完整代码.

//程序说明:将系统中的所有打印机在列表框中列出
//程序变量: PrintDocument prtdoc、string strDefaultPrinter
//编写人:蚕蛹(sillnet@163.net)
//日期:2003-03-20
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace PrinterList
{
 ///
 /// Form1 的摘要说明。
 ///
 public class Form1 : System.Windows.Forms.Form
 {
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.ComboBox printerList;
  ///
  /// 必需的设计器变量。
  ///
  private System.ComponentModel.Container components = null;

  public Form1()
  {
   //
   // Windows 窗体设计器支持所必需的
   //
   InitializeComponent();
   PrintDocument prtdoc = new PrintDocument();
   string strDefaultPrinter = prtdoc.PrinterSettings.PrinterName;//获取默认的打印机名
   foreach(String strPrinter in PrinterSettings.InstalledPrinters)
   //在列表框中列出所有的打印机,
   { 
    printerList.Items.Add(strPrinter);
    if (strPrinter == strDefaultPrinter)//把默认打印机设为缺省值
    {
     printerList.SelectedIndex = printerList.Items.IndexOf(strPrinter);
    }
   }
   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //
  }

  ///
  /// 清理所有正在使用的资源。
  ///
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows Form Designer generated code
  ///
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  ///
  private void InitializeComponent()
  {
   this.label1 = new System.Windows.Forms.Label();
   this.printerList = new System.Windows.Forms.ComboBox();
   this.SuspendLayout();
  //
  // label1
   //
   this.label1.Location = new System.Drawing.Point(8, 24);
   this.label1.Name = “label1“;
   this.label1.Size = new System.Drawing.Size(72, 16);
   this.label1.TabIndex = 0;
   this.label1.Text = “选择打印机:“;
   //
   // printerList
   //
   this.printerList.Location = new System.Drawing.Point(88, 22);
   this.printerList.Name = “printerList“;
   this.printerList.Size = new System.Drawing.Size(192, 21);
   this.printerList.TabIndex = 1;
   this.printerList.Text = “当前系统未装打印机“;
   //
   // Form1
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   this.ClientSize = new System.Drawing.Size(288, 61);
   this.Controls.AddRange(new System.Windows.Forms.Control[] {
      this.printerList,
      this.label1});
   this.Name = “Form1“;
   this.Text = “打印机列表“;
   this.ResumeLayout(false);

  }
  #endregion

  ///
  /// 应用程序的主入口点。
  ///
  [STAThread]
  static void Main()
  {
   Application.Run(new Form1());
  }

 }
}

以上代码在windows xp + vc.net 下测试通过,编译后在Windows98上测试通过。
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-11 16:03 , Processed in 0.147494 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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