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

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

点击“预览”按钮后:

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

点击“打印”按钮后:

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

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

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

这幅图就是该虚拟打印机在屏幕上的显示的结果。
这里是测试程序的源代码: // 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(10, 10);
       btnFileName.Size = new Size(60, 24);
       btnFileName.Click += new EventHandler(BtnFileName_Click);      Button btnPrint = new Button();
       btnPrint.Text = "打印";
       btnPrint.Location = new Point(75, 10);
       btnPrint.Size = new Size(60, 24);
       btnPrint.Click += new EventHandler(BtnPrint_Click);      Button btnView = new Button();
       btnView.Text = "预览";
       btnView.Location = new Point(140, 10);
       btnView.Size = new Size(60, 24);
       btnView.Click += new EventHandler(BtnView_Click);      tbxFileName = new TextBox();
       tbxFileName.Text = "PrintFile.cs";
       tbxFileName.Location = new Point(10, 44);
       tbxFileName.Size = new Size(190, 20);
       tbxFileName.ReadOnly = true;
       tbxFileName.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);      Controls.AddRange(new Control[]{btnFileName, btnPrint, btnView, tbxFileName});
       Text = "文本文件打印程序";
       ClientSize = new Size(210, 80);      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());
     }
   }
 }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.

这里是该类的源代码:

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 == null) break;
           }
           if (line == null) return;
           currPage++;
         }
         if (currPage > ev.PageSettings.PrinterSettings.ToPage) return;
       }
       for (int count = 0; count < linesPerPage; count++)
       {
         line = srToPrint.ReadLine();
         if (line == null) break;
         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;
     }
   }
 }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.

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