zoukankan      html  css  js  c++  java
  • C# 文本文件打印类库(C#)

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

    这里是该类的源代码:

    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;
        }
      }
    }
    View Code

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

  • 相关阅读:
    Android开发如何定制framework层服务
    Intellij IDEA通过SVN导入基于Springboot的maven项目以及对已有项目做更新
    intelliJ IDEA 怎么添加本地的idea web项目
    Android热修复之AndFix使用教程
    iOS友盟分享的使用总结
    iOS 传感器集锦
    IOS CALayer的属性和使用
    Swift使用Alamofire实现网络请求
    Android踩坑随笔Fragment中onActivityResult方法不被调用
    上周热点回顾(4.30-5.6)团队
  • 原文地址:https://www.cnblogs.com/weixing/p/3285443.html
Copyright © 2011-2022 走看看