@TOC)
创建一个类。
Namespace DgPrint
Public Class ClassPrint
Private StrFormat As StringFormat '单元格内容
Private RowPos As Integer '当前打印行
Private NewPage As Boolean '判断是否为新页
Private PageNo As Integer '打印的页数
Private CellHeight As Integer '打印的单元格高度
Private RowsPerPage As Integer '每页的行数
Private PrintDoc As New Printing.PrintDocument() '用于打印的PrintDocument Object
Private PageSetupDialog1 As New PageSetupDialog()
Private ColumnLefts As New ArrayList() '列的左坐标
Private ColumnWidths As New ArrayList() '列的宽度
Private PrintTitles As String = "" '列的标题
Private AvailableColumns As New List(Of String)() 'DataGridView中可见的列
Private HeaderHeight As Integer = 0
Private DGV As DataGridView
Dim Font As New Font("宋体", 8) '单元格字体格式
Dim Font_BT As New Font("宋体", 18) '打印标题字体格式
Dim Font_C As New Font("宋体", 10) '列标题字体格式
'打印
Public Sub Print(ByVal DGV As DataGridView, ByVal Title As String)
Dim Ppvw As PrintPreviewDialog
Try
'获取要打印的DataGridView
Me.DGV = DGV
'获取DataGridView中有可见的列标题
AvailableColumns.Clear()
For Each c As DataGridViewColumn In DGV.Columns
If c.Visible = True Then
AvailableColumns.Add(c.HeaderText)
End If
Next
'显示打印属性窗体
'-------------------------------------------------------------------------------------------
'PrintTitles = Title
'RowsPerPage = 0
'PrintDoc.DocumentName = ""
'Dim Dia As New PageSetupDialog
'Dia.Document = PrintDoc
'Dia.PageSettings = PrintDoc.DefaultPageSettings
'If Dia.ShowDialog() <> DialogResult.OK Then
' Return
'End If
'-------------------------------------------------------------------------------------------
PrintTitles = Title
RowsPerPage = 0
PrintDoc.DocumentName = ""
Dim Dia As New PrintDialog
Dia.PrintToFile = true
Dia.Document = PrintDoc
Dia.UseEXDialog = True
If Dia.ShowDialog() <> DialogResult.OK Then
Return
End If
Ppvw = New PrintPreviewDialog()
Ppvw.WindowState = FormWindowState.Maximized
Ppvw.Document = PrintDoc
'显示打印预览页
AddHandler PrintDoc.BeginPrint, New System.Drawing.Printing.PrintEventHandler(AddressOf PrintGridDoc_BeginPrint)
AddHandler PrintDoc.PrintPage, New System.Drawing.Printing.PrintPageEventHandler(AddressOf PrintGridDoc_PrintPage)
If Ppvw.ShowDialog() <> DialogResult.OK Then
RemoveHandler PrintDoc.BeginPrint, New System.Drawing.Printing.PrintEventHandler(AddressOf PrintGridDoc_BeginPrint)
RemoveHandler PrintDoc.PrintPage, New System.Drawing.Printing.PrintPageEventHandler(AddressOf PrintGridDoc_PrintPage)
Return
End If
'打印文件
PrintDoc.Print()
RemoveHandler PrintDoc.BeginPrint, New System.Drawing.Printing.PrintEventHandler(AddressOf PrintGridDoc_BeginPrint)
RemoveHandler PrintDoc.PrintPage, New System.Drawing.Printing.PrintPageEventHandler(AddressOf PrintGridDoc_PrintPage)
Catch ex As Exception
Finally
End Try
End Sub
Private Sub PrintGridDoc_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs)
Try
StrFormat = New StringFormat()
StrFormat.Alignment = StringAlignment.Center '居中
StrFormat.LineAlignment = StringAlignment.Center
StrFormat.Trimming = StringTrimming.EllipsisCharacter
ColumnLefts.Clear()
ColumnWidths.Clear()
CellHeight = 0
RowsPerPage = 0
PageNo = 1
NewPage = True
RowPos = 0 '当前打印行
Catch ex As Exception
End Try
End Sub
Private Sub PrintGridDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim TmpWidth As Integer, i As Integer
Dim TmpTop As Integer = e.MarginBounds.Top + 30
Dim TmpLeft As Integer = e.MarginBounds.Left + 20
Try
If PageNo = 1 Then
For Each DGVCol As DataGridViewColumn In DGV.Columns
If DGVCol.Visible Then
'获取列的宽度和高度
TmpWidth = DGVCol.Width
HeaderHeight = 44
'获取列的宽度、高度及类型
ColumnLefts.Add(TmpLeft)
ColumnWidths.Add(TmpWidth)
TmpLeft += TmpWidth
End If
Next
End If
'逐行打印当前页
While RowPos < DGV.Rows.Count
Dim DGVRow As DataGridViewRow = DGV.Rows(RowPos)
CellHeight = GetFitHeightOfRow(RowPos, e) '可将单元格高度修改为固定值
'当前页能否打印完剩余行?
If TmpTop + CellHeight >= e.MarginBounds.Height + e.MarginBounds.Top - 10 Then
'不能
DrawGridFooter(e, RowsPerPage)
NewPage = True
PageNo += 1
e.HasMorePages = True
Return
Else
If NewPage Then
'打印标题
'e.Graphics.DrawString(PrintTitles, New Font(Font_BT, FontStyle.Bold), Brushes.Black,
'e.MarginBounds.Width - e.Graphics.MeasureString(PrintTitles, New Font(Font_BT, FontStyle.Bold),
'e.MarginBounds.Width).Width, e.MarginBounds.Top - e.Graphics.MeasureString(PrintTitles, New Font(Font_BT,
'FontStyle.Bold), e.MarginBounds.Width).Height + 33, StrFormat)
e.Graphics.DrawString(PrintTitles, New Font(Font_BT, FontStyle.Bold), Brushes.Black,
e.MarginBounds.Width / 2, e.MarginBounds.Top, StrFormat)
'e.Graphics.DrawString(PrintTitles, New Font(Font_BT, FontStyle.Bold), Brushes.Black,
'e.MarginBounds.Width / 2, e.MarginBounds.Top - e.Graphics.MeasureString(PrintTitles, New Font(Font_BT,
'FontStyle.Bold), e.MarginBounds.Width).Height + 40, StrFormat)
Dim s As [String] = DateTime.Now.ToLongDateString() & " " & DateTime.Now.ToShortTimeString()
'e.Graphics.DrawString("制表时间:" & s & " 制表人:" & Temp_UserName, New Font(Font, FontStyle.Bold), Brushes.Black,
e.Graphics.DrawString("制表时间:" & s & Space(50) & "制表人:", New Font(Font, FontStyle.Bold), Brushes.Black,
e.MarginBounds.Width / 5, e.MarginBounds.Top - e.Graphics.MeasureString(PrintTitles,
New Font(New Font(Font, FontStyle.Bold), FontStyle.Bold), e.MarginBounds.Width).Height + 40)
i += 1
'打印列表头
TmpTop = e.MarginBounds.Top + 50
i = 0
For Each DGVCol As DataGridViewColumn In DGV.Columns
If DGVCol.Visible = True Then
e.Graphics.FillRectangle(New SolidBrush(Color.LightGray), New Rectangle(CInt(ColumnLefts(i)), TmpTop, CInt(ColumnWidths(i)), HeaderHeight))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(ColumnLefts(i)), TmpTop, CInt(ColumnWidths(i)), HeaderHeight))
e.Graphics.DrawString(DGVCol.HeaderText, New Font(Font_C, FontStyle.Bold), New SolidBrush(Color.Black),
New RectangleF(CInt(ColumnLefts(i)), TmpTop, CInt(ColumnWidths(i)), HeaderHeight), StrFormat)
i += 1
End If
Next
NewPage = False
TmpTop += HeaderHeight
End If
'打印各列内容
i = 0
For Each Cel As DataGridViewCell In DGVRow.Cells
If DGV.Columns(Cel.ColumnIndex).Visible = True Then
e.Graphics.DrawString(Cel.Value.ToString(), Font, New SolidBrush(Color.Black), New RectangleF(CInt(ColumnLefts(i)),
CSng(TmpTop), CInt(ColumnWidths(i)), CSng(CellHeight)), StrFormat)
'表格边界
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(ColumnLefts(i)), TmpTop, CInt(ColumnWidths(i)), CellHeight))
i += 1
End If
Next
TmpTop += CellHeight
End If
RowPos += 1
'计算每页打印多少行
If PageNo = 1 Then
RowsPerPage += 1
End If
End While
If RowsPerPage = 0 Then
Return
End If
'打印页脚
DrawGridFooter(e, RowsPerPage)
e.HasMorePages = False
PrintDoc.DocumentName = PrintTitles
Catch ex As Exception
End Try
End Sub
Private Sub DrawGridFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Integer)
Dim Cnt As Double = 0
Cnt = DGV.Rows.Count - 1
Dim PageNum As String = "第" & PageNo.ToString() & "页,共" & Math.Ceiling(Cnt / RowsPerPage).ToString() & "页"
e.Graphics.DrawString(PageNum, Font, Brushes.Black, e.MarginBounds.Width / 2, e.MarginBounds.Top + e.MarginBounds.Height - 20)
End Sub
'计算出最大行高
Private Function GetFitHeightOfRow(ByVal RowNum As Integer, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim i As Integer, j As Integer, k As Integer
Dim TmpWidth As Double = 0
Dim TmpHight As Double = 0
For i = 0 To DGV.Columns.Count - 1
If Convert.ToString(DGV.Rows(RowNum).Cells(i).Value) = "" Then
Continue For
End If
TmpWidth = e.Graphics.MeasureString(DGV.Rows(RowNum).Cells(i).Value, New Font(Font, FontStyle.Regular)).Width
TmpHight = CType(e.Graphics.MeasureString(DGV.Rows(RowNum).Cells(i).Value, New Font(Font, FontStyle.Regular)).Height, Integer)
j = Roundup((TmpWidth + 40), (DGV.Columns(i).Width))
If j * TmpHight > k Then
k = j * TmpHight
End If
Next
If k > 30 Then
GetFitHeightOfRow = k
Else
GetFitHeightOfRow = 30
End If
End Function
'为四舍五入中舍弃部分+1
Private Function Roundup(ByVal i As Double, ByVal j As Double)
Dim k As Double
k = i / j
If k > (CType(k, Integer)) Then
Roundup = k + 1
Else
Roundup = k
End If
End Function
End Class
End Namespace
然后在打印按钮中填入一下代码:
Private Sub BtnPrint_Click(sender As Object, e As EventArgs) Handles BtnPrint.Click
Dim DgvPrint As New Dgprint.ClassPrint
DgvPrint.Print(DataGridViewAccess, Me.Text)
End Sub