風之力

导航

C#实现完整文档打印功能

在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .net Framework的打印功能都以组件的方式提供,为程序员提供了很大的方便,但是这几个组件的使用还是很复杂的,有必要解释一下.
    打印操作通常包括以下四个功能
1 打印设置 设置打印机的一些参数比如更改打印机驱动程序等    
2 页面设置 设置页面大小纸张类型等    
3 打印预览 类似于word中的打印预览    
4 打印 
    实现打印功能的核心是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( ) );
        }
    }
}
    

posted on 2007-11-06 09:42  ZY.Zhou  阅读(916)  评论(0编辑  收藏  举报