上篇博客也已经说到,在实现打印时首先要有打印文档,.NET把打印文档抽象成了一个类PrintDocument,该类在打印过程中必然会用到,它封装了打印的内容,可以在该对象中添加绘制图文。
在使用时通常创建 PrintDocument 类的实例,设置属性(例如 DocumentName 和 PrinterSettings),并调用 Print 方法来开始打印过程。 处理 PrintPage 事件指定打印输出的位置,使用 PrintPageEventArgs的 Graphics Graphics 属性。
a. 常用方法:Print()
b. 常用事件:BeginPrint在调用Print方法时并且在打印文档的第一页之前发生、EndPrint打印完文档的最后一页时发生、PrintPage当需要为当前页打印的输出时发生。
我们来看一个打印的实例,业务说明:在C:\My Documents\MyFile.txt文件内读取要打印的内容,在单击printButton按钮后创建新的PrintDocument对象,并为其制定PrintPage事件。
清单一:printButton按钮事件,读取数据流,创建打印文档,并为文档添加事件。使用加载文件对话框来选择需要打印的文档,这里限制的文档类型只能是txt。
''' <summary> ''' 加载打印文件事件,加载txt文件 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim strFileName As String Dim strFileType As String Me.OpenFileDialog1.ShowDialog() TextBox1.Text = OpenFileDialog1.FileName strFileName = OpenFileDialog1.SafeFileName strFileType = strFileName.ToString.Trim.Remove(0, strFileName.IndexOf(".") + 1) If strFileType <> "txt" Then MsgBox("请选择打印文件,文件类型必须为txt") End If End Sub ''' <summary> ''' 打印按钮事件 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub printButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles printButton.Click Try streamToPrint = New StreamReader("C:\My Documents\MyFile.txt") '读取要打印的数据流 Try printFont = New Font("Arial", 10) Dim pd As New PrintDocument() '创建一个新的打印文档 AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage '为打印文档指定打印事件 pd.Print() Finally streamToPrint.Close() '关闭数据流 End Try Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub
''' <summary> ''' PrintPage事件,当每一页被打印时发生 ''' </summary> ''' <param name="sender"></param> ''' <param name="ev"></param> ''' <remarks></remarks> Private Sub pd_PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs) Dim linesPerPage As Single = 0 Dim yPos As Single = 0 Dim count As Integer = 0 Dim leftMargin As Single = ev.MarginBounds.Left Dim topMargin As Single = ev.MarginBounds.Top Dim line As String = Nothing ' Calculate the number of lines per page. linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) ' Print each line of the file. While count < linesPerPage line = streamToPrint.ReadLine() If line Is Nothing Then Exit While End If yPos = topMargin + count * printFont.GetHeight(ev.Graphics) ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, New StringFormat()) count += 1 End While ' If more lines exist, print another page. If (line IsNot Nothing) Then ev.HasMorePages = True Else ev.HasMorePages = False End If End Sub
通常我们所见的打印对话框有三种,分别是打印预览、页面设置、打印机设置。打印预览可以在打印前可视化的查看文档,但是一般情况下内容不可编辑,后两个对话框则控制着打印的过程,通过页面设置对话框来调整页面类型及打印的类型,最后通过打印对话框来选择打印机或者打印的页数等。
''' <summary> ''' 打印预览函数 ''' </summary> ''' <param name="pb">需要预览的文档</param> ''' <returns></returns> ''' <remarks></remarks> Private Function PrintPreview(ByVal pb As PrintDocument) As Boolean Dim printPre As PrintPreviewDialog '创建一个打印预览对话框 printPre = New PrintPreviewDialog printPre.Document = pb '为对话框指定打印文档 printPre.ShowDialog() '显示打印预览 Return True End Function
这里我们看看下图的页面设置的两个属性,通过设置属性值的真假可以动态的指定内容是否可用。
''' <summary> ''' 打印页面设置函数 ''' </summary> ''' <param name="pb">要打印的文档</param> ''' <returns></returns> ''' <remarks></remarks> Private Function PrintPageSet(ByVal pb As PrintDocument) As Boolean Dim PrintPage As PageSetupDialog PrintPage = New PageSetupDialog PrintPage.Document = pb PrintPage.ShowDialog() Return True End Function
PrintDialog类允许用户从已安装的打印机中选择一台打印机,选择打印份数和其它一些设置,如布局和打印纸张来源。
Note:基本常用的属性在下图中已经标明,打印弹出的对话框是Win XP样式显示的,想要应用显示必须设置UseEXDialog属性。
Note:UserEXDialog属性,在高版本的Win系统中该属性值为True时调用PrintDialog的Show方法时才会显示如下的打印窗体。
代码清单:打印对话框,当打印时指定文档属性,对于手写的PrintDialog对象需要设置UseEXDialog属性为True才可以进行打印。
''' <summary> ''' 打印对话框 ''' </summary> ''' <param name="pb">打印需要的文档</param> ''' <returns></returns> ''' <remarks></remarks> Private Function Print(ByVal pb As PrintDocument) As Boolean Dim PrintDialog As PrintDialog '声明打印对话框 PrintDialog = New PrintDialog '创建一个打印对话框 PrintDialog.Document = pb '为打印对话框添加需要打印的文档 PrintDialog.UseEXDialog = True '设置对话框的显示属性 PrintDialog.ShowDialog() '显示对话框,如果打印对话框是动态创建的必须指定该属性才能显示窗体 Return True End Function
有关打印的文章写到这里已经结束,现在回头想想,从开始的打印解析中可以看出.NET打印封装了底层的API只提供给了用户直接操作的类,很好的符合了编程原则。然后,对打印的对话框进行了解析并用代码实现了打印的实例,很简单,但有一些细节需要注意,如UseEXDialog属性,在高版本的Win系统中需要设置为True才能显示PrintDialog窗体,最后总结一句话:思想上移,行动下移。