您的位置:首页 > 编程语言 > C#

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

2007-04-28 10:20 253 查看
我写了一个打印文本文件的类库,功能包括:打印预览、打印。打印时可以选择打印机,可以指定页码范围。调用方法非常简单:
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(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());


}


}


}



这里是该类的源代码:


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;


}


}


}



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

还可以在 TextFilePrinter 类中增加以下方法:
public void PrintToDefault()
{
using (srToPrint = new StreamReader(fileName, theEncode))
{
GetPrintDocument().Print();
}
}
该方法直接将文本文件打印到默认的打印机,而不是弹出一个打印对话框让你选择打印机。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: