Imports System.Drawing.Printing
 Imports System.Drawing.Color
 Imports System.Windows.Forms
 Imports System.Drawing.Font
 Imports System.Drawing.PointF
 Imports System.Windows.Forms.DataGrid
 Imports System.Drawing.Pen
 Imports System.Drawing  ''=======================================
 'DATAGRID控件通用打印类
 '中和科技-孙利臣
 '于2003年05月27日17:05
 '用于打印DATAGRID控件中的数据.'=======================================
 Public Class PrintDataGrid
 '用户可自定义
 Private PrintFont As New Font("宋体", 10) '当前要打印文本的字体及字号
 Private PrintLines As Integer = 50 '当前页共要分成多少行.
 Private PrintRecordNumber As Integer = 45 '当前页共要打印的记录的行数'以下为模块内部使用
 Private DataGridSource As DataGrid
 Private ev As PrintPageEventArgs
 Private PrintDataGrid As PrintDocument
 Private PrintPriview As PrintPreviewDialog
 Private PageSetup As PageSetupDialog
 Private PrintScale As Double = 1 '当前要打印的数据与DATAGRID控件内数据的比例Private DataGridColumn As DataColumn
 Private DataGridRow As DataRow
 Private DataGridTable As DataTablePrivate Cols As Integer '当前要打印的列
 Private Rows As Integer = 1 '当前要打印的行Private ColsCount As Integer '当前DATAGRID共有多少列
Private PrintingLineNumber As Integer = 0 '当前正要打印的行号
 Private PageRecordNumber As Integer '当前要所要打印的记录行数,由计算得到.Dim X_unit As Integer '表的基本单位
 Dim Y_unit As IntegerPrivate PrintingPageNumber As Integer = 0 '正要打印的页号
Private PageNumber As Integer '共需要打印的页数
 Private PrintRecordLeave As Integer '当前还有多少页没有打印
 Private PrintRecordComplete As Integer = 0 '已经打印完的记录数Sub New(ByVal TableSource As DataGrid)
 DataGridSource = TableSource
 DataGridTable = New DataTable()
 DataGridTable = DataGridSource.DataSource()
 ColsCount = DataGridTable.Columns.Count
 End Sub'用户自定义字体及字号
 Public WriteOnly Property setPrintFont() As System.Drawing.Font
 Set(ByVal Value As System.Drawing.Font)
 PrintFont = Value
 End Set
 End Property'设置每页要打印的的记录条数
 Public WriteOnly Property setPrintRecordNumber() As Integer
 Set(ByVal Value As Integer)
 PrintRecordNumber = Value
 End Set
 End Property Public Sub Print()
 Try
 PrintDataGrid = New System.Drawing.Printing.PrintDocument()
 AddHandler PrintDataGrid.PrintPage, AddressOf Me.PrintDataGrid_PrintPage
 'PrintDataTable.Print()'打印机设置对话框
 PageSetup = New PageSetupDialog()
 PageSetup.PageSettings = PrintDataGrid.DefaultPageSettings
 If PageSetup.ShowDialog() = DialogResult.Cancel Then
 Exit Sub
 End If'当前页是横向还是纵向打印
 '计算当前页总共可以打印的行数
 If PrintDataGrid.DefaultPageSettings.Landscape = False Then
 PrintLines = PrintDataGrid.DefaultPageSettings.PaperSize.Height / (PrintFont.Height + 5)
 Else
 PrintLines = PrintDataGrid.DefaultPageSettings.PaperSize.Width / (PrintFont.Height + 5)
 End If '如果用户选择自定义纸张大小打印,则按B5纸打印,不管实际纸张大小
 If PrintDataGrid.DefaultPageSettings.PaperSize.PaperName.ToString = "custom" ThenEnd If
'预览窗口
 PrintPriview = New PrintPreviewDialog()
 PrintPriview.Document = PrintDataGrid
 PrintPriview.ShowDialog()Catch ex As Exception
 MessageBox.Show("error:" & ex.ToString)
 FinallyEnd Try
 End SubPrivate Sub PrintDataGrid_PrintPage(ByVal sender As Object, ByVal ev As System.Drawing.Printing.PrintPageEventArgs)
'A4纸 A4 纸,210 x 297 毫米。
 'B5纸 B5 纸,182 x 257 毫米。Dim strPrint As String '当前要打印的文本
 Dim DrawBrush As New SolidBrush(System.Drawing.Color.Blue) '当前画笔颜色Dim X As Integer '当前要打印的文本的横坐标
 Dim Y As Integer '当前要打印的文本的列坐标Dim DrawPoint As New PointF(X, Y)
Dim row_count As Integer '当前要打印的行
 PrintRecordLeave = DataGridTable.Rows.Count - PrintRecordComplete '还有多少条记录没有打印
 PageNumber = PrintRecordLeave / PrintRecordNumber '共需要打印的页数
 PrintingPageNumber = 0 '因为每打印一个新页都要计算还有多少页没有打印所以以打印的页数初始为0 '将当前页分成基本的单元
 If PrintDataGrid.DefaultPageSettings.Landscape = True Then
 X_unit = PrintDataGrid.DefaultPageSettings.PaperSize.Height / (DataGridTable.Columns.Count + 2)
 Y_unit = PrintDataGrid.DefaultPageSettings.PaperSize.Width / PrintLinesElse
 X_unit = PrintDataGrid.DefaultPageSettings.PaperSize.Width / (DataGridTable.Columns.Count + 2)
 Y_unit = PrintDataGrid.DefaultPageSettings.PaperSize.Height / PrintLinesEnd If
 '计算,余下的记录条数是否还可以在一页打印,不满一页时为假
 If DataGridTable.Rows.Count - PrintingPageNumber * PrintRecordNumber >= PrintRecordNumber Then
 PageRecordNumber = PrintRecordNumber
 Else
 PageRecordNumber = (DataGridTable.Rows.Count - PrintingPageNumber * PrintRecordNumber) Mod PrintRecordNumber
 End If While PrintingPageNumber <= PageNumber
'文档标题----------------打印开始
 strPrint = DataGridSource.CaptionText '文档标题
 DrawPoint = New PointF(X_unit, Y_unit)
 ev.Graphics.DrawString(strPrint, PrintFont, DrawBrush, DrawPoint)
 '文档标题----------------打印结束'得到DATAGRID的所有列名
 Dim ColumnText(DataGridTable.Columns.Count) As String
 Dim Table As IntegerFor Cols = 0 To DataGridTable.Columns.Count - 1
ColumnText(Cols) = DataGridTable.Columns(Cols).ToString '得到当前所有的列名
DrawPoint = New PointF(X_unit * (Cols + 1), Y_unit * 2)
 ev.Graphics.DrawString(ColumnText(Cols), PrintFont, DrawBrush, DrawPoint)Next
DrawPoint = New PointF(X_unit, Y_unit * 2)
 Call DrawLine(DrawPoint, ev) '画线
 '结束---------------------得到DATAGRID的所有列名 Dim PrintingLine As Integer = 0 '当前页面已经打印的记录行数
'用于确定是否换页的标记
 Dim strUpData As String = "" '当前数据的前一个数据
 Dim strNonce As String = "" '当前数据While PrintingLine < PageRecordNumber
DataGridRow = DataGridTable.Rows(PrintRecordComplete) '确定要当前要打印的记录的行号
 For Cols = 0 To DataGridTable.Columns.Count - 1
 DrawPoint.X = X_unit * (Cols + 1)
 DrawPoint.Y = Y_unit * (PrintingLine + 1 + 2)If Cols = 0 Then '所要根据此列的数据分页
 If strUpData <> "" Then 'And strNonce <> ""
 If strUpData <> DataGridRow(ColumnText(0)) Then
 ev.HasMorePages = True
 Exit SubEnd If
 End If
 End Ifev.Graphics.DrawString(DataGridRow(ColumnText(Cols)), PrintFont, DrawBrush, DrawPoint)
 strUpData = DataGridRow(ColumnText(0)) '当前行数据打印完成后,将打记录的第一列保存,(也可不用此语句,只为明确)
 NextDrawPoint.X = X_unit * 1
 DrawPoint.Y = Y_unit * (PrintingLine + 1 + 2)Call DrawLine(DrawPoint, ev)
PrintingLine += 1
 PrintRecordComplete += 1'打印完最后一条记录后结束打印.
 '如:当前有500条记录.从0开始打印,实际打印的为第一条记录.则打印500条时实际的是第501条记录.也就是最后一条
 'datagridtable.rows.count得到就是表内的实际记录条数,共有多少条记录(从1开始),当
 'printrecordcomplete>=datagridtable.rows.count也就是当前已经打印到了500条,加1后将要打印第501条,越界,则结束.
 If PrintRecordComplete >= DataGridTable.Rows.Count Then
 ev.HasMorePages = False
 Exit Sub
 End If
 End WhilePrintingPageNumber += 1
 If PrintingPageNumber > PageNumber Then
 ev.HasMorePages = False
 Elseev.HasMorePages = True
 Exit While
 End IfEnd While
End Sub
 '画线 只必指定当前行的打印文字的开始位置就可,x,y为当前行文字的打印位置
 Private Sub DrawLine(ByVal point As PointF, ByVal ev As System.Drawing.Printing.PrintPageEventArgs)
 Dim blackPen As New Pen(System.Drawing.Color.Black, 1) ev.Graphics.DrawLine(blackPen, point.X, point.Y + PrintFont.Height, point.X * (ColsCount + 1), point.Y + PrintFont.Height)
End Sub
End Class
``````````````````````````````````````````````````````
Private aa As PrintDataGrid.PrintDataGrid
aa = New PrintDataGrid.PrintDataGrid(DataGrid1)
aa.setPrintFont() = New System.Drawing.Font("宋体", 12) '打印文本的字体
 aa.setPrintRecordNumber = 30 '每页要打印的记录行数aa.Print()