文本文件打印类库(C#)

来源:互联网 发布:hp清零软件 编辑:程序博客网 时间:2024/06/06 18:58

我写了一个打印文本文件的类库,功能包括:打印预览、打印。打印时可以选择打印机,可以指定页码范围。调用方法非常简单:
TextFilePrinter p = new TextFilePrinter(tbxFileName.Text);
p.View();  // 打印预览
p.Print(); // 打印文件
使用 TextFilePrinter 类的以下构造函数可以指定打印时使用的字体:
TextFilePrinter(string fileName, Encoding theEncode, Font theFont)
下面测试程序运行时的截图:

点击“预览”按钮后:

点击“打印”按钮后:

这幅图中的打印机:“Microsoft Office Doument Image Writer”是 Microsoft Office 2003 软件提供一个虚拟打印机,用来调试打印程序非常方便(使用“打印预览”也可以调试打印程序,但“打印预览”只能使用默认的打印机和默认的打印属性,也不能设置页码范围),可以设置打印属性和页码范围以及打印份数。使用它来调试打印程序,可以节省不少打印纸。为建设节约型社会作贡献 :) 

这幅图就是该虚拟打印机在屏幕上的显示的结果。
这里是测试程序的源代码:

// PrintFile.cs - 文件打印程序
// 编译方法: csc /t:winexe PrintFile.cs TextFilePrinter.cs


using System;
using
 System.Drawing;
using
 System.Windows.Forms;
using
 Skyiv.Util;

namespace
 Skyiv.Ben.Test
{
  
class
 PrintFileForm : Form
  
{
    TextBox tbxFileName;
    
    
public
 PrintFileForm()
    
{
      SuspendLayout();
      
      Button btnFileName 
= new
 Button();
      btnFileName.Text 
= "文件名"
;
      btnFileName.Location 
= new Point(1010
);
      btnFileName.Size 
= new Size(6024
);
      btnFileName.Click 
+= new
 EventHandler(BtnFileName_Click);

      Button btnPrint 
= new
 Button();
      btnPrint.Text 
= "打印"
;
      btnPrint.Location 
= new Point(7510
);
      btnPrint.Size 
= new Size(6024
);
      btnPrint.Click 
+= new
 EventHandler(BtnPrint_Click);

      Button btnView 
= new
 Button();
      btnView.Text 
= "预览"
;
      btnView.Location 
= new Point(14010
);
      btnView.Size 
= new Size(6024
);
      btnView.Click 
+= new
 EventHandler(BtnView_Click);

      tbxFileName 
= new
 TextBox();
      tbxFileName.Text 
= "PrintFile.cs"
;
      tbxFileName.Location 
= new Point(1044
);
      tbxFileName.Size 
= new Size(19020
);
      tbxFileName.ReadOnly 
= true
;
      tbxFileName.Anchor 
= (AnchorStyles.Top | AnchorStyles.Left |
 AnchorStyles.Right);

      Controls.AddRange(
new Control[]{btnFileName, btnPrint, btnView, tbxFileName}
);
      Text 
= "文本文件打印程序"
;
      ClientSize 
= new Size(21080
);

      ResumeLayout(
false
);
    }

    
    
void BtnFileName_Click(object sender, EventArgs e)
    
{
      OpenFileDialog dlg 
= new
 OpenFileDialog();
      
if(dlg.ShowDialog() != DialogResult.OK) return
;
      tbxFileName.Text 
=
 dlg.FileName;
    }


    
void BtnPrint_Click(object sender, EventArgs e)
    
{
      TextFilePrinter p 
= new
 TextFilePrinter(tbxFileName.Text);
      p.Print();
    }

    
    
void BtnView_Click(object sender, EventArgs e)
    
{
      TextFilePrinter p 
= new
 TextFilePrinter(tbxFileName.Text);
      p.View();
    }

    
    
static void Main()
    
{
      Application.Run(
new
 PrintFileForm());
    }

  }

}

这里是该类的源代码:

using System;
using
 System.Drawing;
using
 System.Drawing.Printing;
using
 System.Windows.Forms;
using
 System.IO;
using
 System.Text;

namespace
 Skyiv.Util
{
  
sealed class
 TextFilePrinter
  
{
    
string
 fileName;
    Encoding theEncode;
    Font theFont;
    StreamReader srToPrint;
    
int
 currPage;

    
public TextFilePrinter(string
 fileName)
      : 
this(fileName, Encoding.GetEncoding("GB18030"), new Font("新宋体"10
))
    
{
    }


    
public TextFilePrinter(string fileName, Encoding theEncode, Font theFont)
    
{
      
this.fileName =
 fileName;
      
this.theEncode =
 theEncode;
      
this.theFont =
 theFont;
    }


    
public void Print()
    
{
      
using (srToPrint = new
 StreamReader(fileName, theEncode))
      
{
        PrintDialog dlg 
= new
 PrintDialog();
        dlg.Document 
=
 GetPrintDocument();
        dlg.AllowSomePages 
= true
;
        dlg.AllowPrintToFile 
= false
;
        
if (dlg.ShowDialog() ==
 DialogResult.OK) dlg.Document.Print();
      }

    }


    
public void View()
    
{
      
using (srToPrint = new
 StreamReader(fileName, theEncode))
      
{
        PrintPreviewDialog dlg 
= new
 PrintPreviewDialog();
        dlg.Document 
=
 GetPrintDocument();
        dlg.ShowDialog();
      }

    }


    PrintDocument GetPrintDocument()
    
{
      currPage 
= 1
;
      PrintDocument doc 
= new
 PrintDocument();
      doc.DocumentName 
=
 fileName;
      doc.PrintPage 
+= new
 PrintPageEventHandler(PrintPageEvent);
      
return
 doc;
    }


    
void PrintPageEvent(object sender, PrintPageEventArgs ev)
    
{
      
string line = null
;
      
float linesPerPage = ev.MarginBounds.Height /
 theFont.GetHeight(ev.Graphics);
      
bool isSomePages = ev.PageSettings.PrinterSettings.PrintRange ==
 PrintRange.SomePages;
      
if
 (isSomePages)
      
{
        
while (currPage <
 ev.PageSettings.PrinterSettings.FromPage)
        
{
          
for (int count = 0; count < linesPerPage; count++
)
          
{
            line 
=
 srToPrint.ReadLine();
            
if (line == nullbreak
;
          }

          
if (line == nullreturn;
          currPage
++
;
        }

        
if (currPage > ev.PageSettings.PrinterSettings.ToPage) return;
      }

      
for (int count = 0; count < linesPerPage; count++)
      
{
        line 
=
 srToPrint.ReadLine();
        
if (line == nullbreak
;
        ev.Graphics.DrawString(line, theFont, Brushes.Black, ev.MarginBounds.Left,
          ev.MarginBounds.Top 
+ (count * theFont.GetHeight(ev.Graphics)), new
 StringFormat());
      }

      currPage
++;
      
if (isSomePages && currPage > ev.PageSettings.PrinterSettings.ToPage) return
;
      
if (line != null) ev.HasMorePages = true
;
    }

  }

}

这些程序都相当简当明了,这里就不再解释了。
这个类库有个缺点:当文本文件中的一行不能在打印纸的一行中打印完时,该行的后半部就丢失了。
 

还可以在 TextFilePrinter 类中增加以下方法:
public void PrintToDefault()
{
  using (srToPrint = new StreamReader(fileName, theEncode))
  {
    GetPrintDocument().Print();
  }
}
该方法直接将文本文件打印到默认的打印机,而不是弹出一个打印对话框让你选择打印机。