- Imports System.Drawing
- Imports System.Drawing.Pen
- Imports System.Drawing.Font
- Imports System.Drawing.PointF
- Imports System.Drawing.Color
- Imports System.Drawing.Printing
- Imports System.Windows.Forms
- Imports System.Windows.Forms.DataGrid
- Public Class PrintDataTable
- '以下用户可自定义
- '当前要打印文本的字体及字号
- Private TableFont As New Font("宋体", 10)
- '表头字体
- Private HeadFont As New Font("宋体", 20, FontStyle.Bold)
- '副表头字体
- Private SubHeadFont As New Font("宋体", 10, FontStyle.Regular)
- '表头文字
- Private HeadText As String
- '副表头左文字
- Private SubHeadLeftText As String
- '副表头右文字
- Private SubHeadRightText As String
- '表头高度
- Private HeadHeight As Integer = 40
- '副表头高度
- Private SubHeadHeight As Integer = 20
- '表脚字体
- Private FootFont As New Font("宋体", 10, FontStyle.Regular)
- '副表脚字体
- Private SubFootFont As New Font("宋体", 10, FontStyle.Regular)
- '表脚文字
- Private FootText As String
- '副表脚左文字
- Private SubFootLeftText As String
- '副表脚右文字
- Private SubFootRightText As String
- '表脚高度
- Private FootHeight As Integer = 30
- '副表脚高度
- Private SubFootHeight As Integer = 20
- '表的基本单位
- Dim XUnit As Integer
- Dim YUnit As Integer = TableFont.Height * 2.5
- '以下为模块内部使用
- Private Ev As PrintPageEventArgs
- Private DataTablePrinter As PrintDocument
- Private DataGridColumn As DataColumn
- Private DataGridRow As DataRow
- Private DataTablePrint As DataTable
- '当前要打印的行
- Private Rows As Integer
- '当前DATAGRID共有多少列
- Private ColsCount As Integer
- '当前正要打印的行号
- Private PrintingLineNumber As Integer
- '当前要所要打印的记录行数,由计算得到
- Private PageRecordNumber As Integer
- '正要打印的页号
- Private PrintingPageNumber As Integer
- '共需要打印的页数
- Private PageNumber As Integer
- '当前还有多少页没有打印
- Private PrintRecordLeave As Integer
- '已经打印完的记录数
- Private PrintRecordComplete As Integer
- Private PLeft As Integer
- Private PTop As Integer
- Private PRight As Integer
- Private PBottom As Integer
- Private PWidth As Integer
- Private PHeigh As Integer
- '当前画笔颜色
- Private DrawBrush As New SolidBrush(System.Drawing.Color.Black)
- '每页打印的记录条数
- Private PrintRecordNumber As Integer
- '总共应该打印的页数
- Private TotalPage As Integer
- Sub New(ByVal TableSource As DataTable)
- DataTablePrint = New DataTable
- DataTablePrint = TableSource
- ColsCount = DataTablePrint.Columns.Count
- End Sub
- '用户自定义字体及字号
- Public WriteOnly Property SetTableFont() As System.Drawing.Font
- Set(ByVal Value As System.Drawing.Font)
- TableFont = Value
- End Set
- End Property
- Public WriteOnly Property SetHeadFont() As System.Drawing.Font
- Set(ByVal Value As System.Drawing.Font)
- HeadFont = Value
- End Set
- End Property
- Public WriteOnly Property SetSubHeadFont() As System.Drawing.Font
- Set(ByVal Value As System.Drawing.Font)
- SubHeadFont = Value
- End Set
- End Property
- Public WriteOnly Property SetFootFont() As System.Drawing.Font
- Set(ByVal Value As System.Drawing.Font)
- FootFont = Value
- End Set
- End Property
- Public WriteOnly Property SetSubFootFont() As System.Drawing.Font
- Set(ByVal Value As System.Drawing.Font)
- SubFootFont = Value
- End Set
- End Property
- Public WriteOnly Property SetHeadText() As String
- Set(ByVal Value As String)
- HeadText = Value
- End Set
- End Property
- Public WriteOnly Property SetSubHeadLeftText() As String
- Set(ByVal Value As String)
- SubHeadLeftText = Value
- End Set
- End Property
- Public WriteOnly Property SetSubHeadRightText() As String
- Set(ByVal Value As String)
- SubHeadRightText = Value
- End Set
- End Property
- Public WriteOnly Property SetFootText() As String
- Set(ByVal Value As String)
- FootText = Value
- End Set
- End Property
- Public WriteOnly Property SetSubFootLeftText() As String
- Set(ByVal Value As String)
- SubFootLeftText = Value
- End Set
- End Property
- Public WriteOnly Property SetSubFootRightText() As String
- Set(ByVal Value As String)
- SubFootRightText = Value
- End Set
- End Property
- Public WriteOnly Property SetHeadHeight() As Integer
- Set(ByVal Value As Integer)
- HeadHeight = Value
- End Set
- End Property
- Public WriteOnly Property SetSubHeadHeight() As Integer
- Set(ByVal Value As Integer)
- SubHeadHeight = Value
- End Set
- End Property
- Public WriteOnly Property SetFootHeight() As Integer
- Set(ByVal Value As Integer)
- FootHeight = Value
- End Set
- End Property
- Public WriteOnly Property SetSubFootHeight() As Integer
- Set(ByVal Value As Integer)
- SubFootHeight = Value
- End Set
- End Property
- Public WriteOnly Property SetCellHeight() As Integer
- Set(ByVal Value As Integer)
- YUnit = Value
- End Set
- End Property
- Public Sub Print()
- Try
- DataTablePrinter = New Printing.PrintDocument
- AddHandler DataTablePrinter.PrintPage, AddressOf DataTablePrinter_PrintPage
- Dim PageSetup As PageSetupDialog
- PageSetup = New PageSetupDialog
- PageSetup.Document = DataTablePrinter
- DataTablePrinter.DefaultPageSettings = PageSetup.PageSettings
- If PageSetup.ShowDialog() = DialogResult.Cancel Then
- Exit Sub
- End If
- PLeft = DataTablePrinter.DefaultPageSettings.Margins.Left
- PTop = DataTablePrinter.DefaultPageSettings.Margins.Top
- PRight = DataTablePrinter.DefaultPageSettings.Margins.Right
- PBottom = DataTablePrinter.DefaultPageSettings.Margins.Bottom
- PWidth = DataTablePrinter.DefaultPageSettings.Bounds.Width
- PHeigh = DataTablePrinter.DefaultPageSettings.Bounds.Height
- '将当前页分成基本的单元
- XUnit = (PWidth - PLeft - PRight) / DataTablePrint.Columns.Count - 1
- PrintRecordNumber = (PHeigh - PTop - PBottom - HeadHeight - SubHeadHeight - FootHeight - SubFootHeight - YUnit) / YUnit
- If DataTablePrint.Rows.Count > PrintRecordNumber Then
- If DataTablePrint.Rows.Count Mod PrintRecordNumber = 0 Then
- TotalPage = DataTablePrint.Rows.Count / PrintRecordNumber
- Else
- TotalPage = DataTablePrint.Rows.Count / PrintRecordNumber + 1
- End If
- Else
- TotalPage = 1
- End If
- DataTablePrinter.DocumentName = TotalPage.ToString
- Dim PrintPriview As PrintPreviewDialog
- PrintPriview = New PrintPreviewDialog
- PrintPriview.Document = DataTablePrinter
- PrintPriview.WindowState = FormWindowState.Maximized
- PrintPriview.ShowDialog()
- Catch ex As Exception
- MsgBox("打印错误,请检查打印设置!", 16, "错误")
- End Try
- End Sub
-
- Private Sub DataTablePrinter_PrintPage(ByVal sender As Object, ByVal Ev As System.Drawing.Printing.PrintPageEventArgs)
- '还有多少条记录没有打印
- PrintRecordLeave = DataTablePrint.Rows.Count - PrintRecordComplete
- If PrintRecordLeave > 0 Then
- If PrintRecordLeave Mod PrintRecordNumber = 0 Then
- PageNumber = PrintRecordLeave / PrintRecordNumber
- Else
- PageNumber = PrintRecordLeave / PrintRecordNumber + 1
- End If
- Else
- PageNumber = 0
- End If
- '正在打印的页数,因为每打印一个新页都要计算还有多少页没有打印所以以打印的页数初始为0
- PrintingPageNumber = 0
- '计算,余下的记录条数是否还可以在一页打印,不满一页时为假
- If DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber >= PrintRecordNumber Then
- PageRecordNumber = PrintRecordNumber
- Else
- PageRecordNumber = (DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber) Mod PrintRecordNumber
- End If
- Dim fmt As New StringFormat
- '上下对齐
- fmt.LineAlignment = StringAlignment.Center
- '自动换行
- fmt.FormatFlags = StringFormatFlags.LineLimit
- '打印区域
- Dim Rect As New Rectangle
- '打印表格线格式
- Dim Pen As New Pen(Brushes.Black, 1)
- While PrintingPageNumber <= PageNumber
- '表头中间对齐
- fmt.Alignment = StringAlignment.Center
- '表头和副表头宽度等于设置区域宽度
- Rect.Width = PWidth - PLeft - PRight
- Rect.Height = HeadHeight
- Rect.X = PLeft
- Rect.Y = PTop
- '打印表头
- Ev.Graphics.DrawString(HeadText, HeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- '副表头左对齐
- fmt.Alignment = StringAlignment.Near
- Rect.Width = (PWidth - PLeft - PRight) / 2 - 1
- Rect.Height = SubHeadHeight
- Rect.Y = PTop + HeadHeight
- '打印副表头左
- Ev.Graphics.DrawString(SubHeadLeftText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- '右副表头文字从右往左排列
- fmt.FormatFlags = StringFormatFlags.DirectionRightToLeft
- '右副表头右对齐
- fmt.Alignment = StringAlignment.Near
- Rect.X = PLeft + (PWidth - PLeft - PRight) / 2
- '打印副表头右
- Ev.Graphics.DrawString(SubHeadRightText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- fmt.Alignment = StringAlignment.Center
- Rect.X = PLeft
- Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + 1) * (YUnit) + SubFootHeight
- Rect.Height = FootHeight
- Rect.Width = PWidth - PLeft - PRight
- '打印表脚
- Ev.Graphics.DrawString(FootText, FootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- '副表左左对齐
- fmt.Alignment = StringAlignment.Far
- Rect.X = PLeft
- Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + 1) * (YUnit)
- Rect.Height = SubFootHeight
- Rect.Width = (PWidth - PLeft - PRight) / 2 - 1
- '打印左表脚
- Ev.Graphics.DrawString(SubFootLeftText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- '副表头右对齐
- fmt.Alignment = StringAlignment.Near
- Rect.X = PLeft + (PWidth - PLeft - PRight) / 2
- If DataTablePrint.Rows.Count = 0 Then
- SubFootRightText = "第" & TotalPage & "页,共" & TotalPage & "页"
- Else
- SubFootRightText = "第" & TotalPage - PageNumber + 1 & "页,共" & TotalPage & "页"
- End If
- '打印右表脚
- Ev.Graphics.DrawString(SubFootRightText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
- '得到datatable的所有列名
- fmt.Alignment = StringAlignment.Center
- Dim ColumnText(DataTablePrint.Columns.Count) As String
- For Cols = 0 To DataTablePrint.Columns.Count - 1
- '得到当前所有的列名
- ColumnText(Cols) = DataTablePrint.Columns(Cols).ToString
- Rect.X = PLeft + XUnit * Cols
- Rect.Y = PTop + HeadHeight + SubHeadHeight
- Rect.Width = XUnit
- Rect.Height = YUnit
- Ev.Graphics.DrawString(ColumnText(Cols), New Font(TableFont, FontStyle.Bold), DrawBrush, RectangleF.op_Implicit(Rect), fmt)
- Ev.Graphics.DrawRectangle(Pen, Rect)
- Next
- '结束---------------------得到datatable的所有列名
- '当前页面已经打印的记录行数
- Dim PrintingLine As Integer = 0
- While PrintingLine < PageRecordNumber
- '确定要当前要打印的记录的行号
- DataGridRow = DataTablePrint.Rows(PrintRecordComplete)
- For Cols = 0 To DataTablePrint.Columns.Count - 1
- Rect.X = PLeft + XUnit * Cols
- Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintingLine + 1) * (YUnit)
- Rect.Width = XUnit
- Rect.Height = YUnit
- If DataGridRow(ColumnText(Cols)) Is System.DBNull.Value = False Then
- Ev.Graphics.DrawString(DataGridRow(ColumnText(Cols)), TableFont, DrawBrush, RectangleF.op_Implicit(Rect), fmt)
- End If
- Ev.Graphics.DrawRectangle(Pen, Rect)
- Next
- PrintingLine += 1
- PrintRecordComplete += 1
- If PrintRecordComplete >= DataTablePrint.Rows.Count Then
- Ev.HasMorePages = False
- PrintRecordComplete = 0
- Exit Sub
- End If
- End While
- PrintingPageNumber += 1
- If PrintingPageNumber >= PageNumber Then
- Ev.HasMorePages = False
- Else
- Ev.HasMorePages = True
- Exit While
- End If
- End While
- End Sub
- '附转换函数
- 'listview转为Datatable函数
- Public Function ListviewToDatatable(ByVal Listview1 As ListView)
- Dim Table1 As New DataTable
- Dim i As Integer
- Dim datacol As DataColumn
- For i = 0 To Listview1.Columns.Count - 1
- datacol = New DataColumn
- datacol.DataType = Type.GetType("System.Object")
- datacol.ColumnName = Listview1.Columns(i).Text.Trim
- Table1.Columns.Add(datacol)
- Next i
- Dim j As Integer
- Dim Datarow1 As DataRow
- For j = 0 To Listview1.Items.Count - 1
- Datarow1 = Table1.NewRow
- For i = 0 To Listview1.Columns.Count - 1
- Datarow1.Item(Listview1.Columns(i).Text.Trim) = Listview1.Items(j).SubItems(i).Text.ToString
- Next i
- Table1.Rows.Add(Datarow1)
- Next j
- Return Table1
- End Function
- '数据集转为Datatable函数
- Public Function DataBaseToDataTable(ByVal SqlDataAdapter1 As Data.SqlClient.SqlDataAdapter, ByVal TableName As String)
- Dim Table1 As New DataTable
- Dim DataSet1 As New DataSet
- DataSet1.Clear()
- SqlDataAdapter1.Fill(DataSet1, TableName)
- Table1 = DataSet1.Tables(TableName)
- Return Table1
- End Function
- End Class