Public Class GridViewPrintHelper
Private strFormat As StringFormat
Private iCellHeight, iCount, iTotalWidth, iHeaderHeight As Integer
Public Property FirstPage As Boolean
Public Property NewPage As Boolean
Private arrColumnLefts As New List(Of Integer)
Private arrColumnWidths As New List(Of Integer)
Public Sub BeginPrint(dgvList As DataGridView, Optional unwantedColsFromStartingPos As Integer = 0)
strFormat = New StringFormat()
strFormat.Alignment = StringAlignment.Near
strFormat.LineAlignment = StringAlignment.Center
strFormat.Trimming = StringTrimming.EllipsisCharacter
arrColumnLefts.Clear()
arrColumnWidths.Clear()
iCellHeight = 0
iCount = 0
FirstPage = True
NewPage = True
If unwantedColsFromStartingPos < 0 Then unwantedColsFromStartingPos = 0
' Calculating Total Widths
iTotalWidth = 0
If unwantedColsFromStartingPos >= dgvList.ColumnCount Then
Throw New Exception("Invalid column count - From GridViewPrint: unwantedColsFromStartingPos param in BeginPrint")
End If
For i = unwantedColsFromStartingPos To (dgvList.ColumnCount - 1)
iTotalWidth += dgvList.Columns(i).Width
Next
End Sub
Public Sub PrintPage(ByVal dgvList As DataGridView, ByVal e As System.Drawing.Printing.PrintPageEventArgs, Optional ByVal unwantedColsFromStartingPos As Integer = 0, Optional ByVal Heading As String = "Summary")
Dim iLeftMargin As Integer = e.MarginBounds.Left
'Set the top margin
Dim iTopMargin As Integer = e.MarginBounds.Top
'Whether more pages have to print or not
Dim bMorePagesToPrint As Boolean = False
Dim iTmpWidth As Integer = 0
'For the first page to print set the cell width and header height
Dim neg As Integer = -1
If FirstPage Then
For Each GridCol As DataGridViewColumn In dgvList.Columns
neg = neg + 1
If neg < unwantedColsFromStartingPos Then
Continue For
End If
iTmpWidth = CInt(Math.Floor(CDbl(CDbl(GridCol.Width) / CDbl(iTotalWidth) * CDbl(iTotalWidth) * (CDbl(e.MarginBounds.Width) / CDbl(iTotalWidth)))))
iHeaderHeight = CInt(e.Graphics.MeasureString(GridCol.HeaderText, GridCol.InheritedStyle.Font, iTmpWidth).Height) + 11
' Save width and height of headers
arrColumnLefts.Add(iLeftMargin)
arrColumnWidths.Add(iTmpWidth)
iLeftMargin += iTmpWidth
Next
End If
Dim iRow As Integer = 0
'Loop till all the grid rows not get printed
While iRow <= dgvList.Rows.Count - 1
Dim GridRow As DataGridViewRow = dgvList.Rows(iRow)
'Set the cell height
iCellHeight = GridRow.Height + 5
Dim iCount As Integer = 0
'Check whether the current page settings allows more rows to print
If iTopMargin + iCellHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
NewPage = True
FirstPage = False
bMorePagesToPrint = True
Exit While
Else
If NewPage Then
'Draw Header
e.Graphics.DrawString(Heading, New Font(dgvList.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Heading, New Font(dgvList.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
Dim strDate As [String] = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString()
'Draw Date
e.Graphics.DrawString(strDate, New Font(dgvList.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(strDate, New Font(dgvList.Font, FontStyle.Bold), e.MarginBounds.Width).Width), e.MarginBounds.Top - e.Graphics.MeasureString("Customer Summary", New Font(New Font(dgvList.Font, FontStyle.Bold), FontStyle.Bold), e.MarginBounds.Width).Height - 13)
'Draw Columns
iTopMargin = e.MarginBounds.Top
neg = -1
For Each GridCol As DataGridViewColumn In dgvList.Columns
neg = neg + 1
If neg < unwantedColsFromStartingPos Then
Continue For
End If
e.Graphics.FillRectangle(New SolidBrush(Color.LightGray), New Rectangle(CInt(arrColumnLefts(iCount)), iTopMargin, CInt(arrColumnWidths(iCount)), iHeaderHeight))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(arrColumnLefts(iCount)), iTopMargin, CInt(arrColumnWidths(iCount)), iHeaderHeight))
e.Graphics.DrawString(GridCol.HeaderText, GridCol.InheritedStyle.Font, New SolidBrush(GridCol.InheritedStyle.ForeColor), New RectangleF(CInt(arrColumnLefts(iCount)), iTopMargin, CInt(arrColumnWidths(iCount)), iHeaderHeight), strFormat)
iCount += 1
Next
NewPage = False
iTopMargin += iHeaderHeight
End If
iCount = 0
'Draw Columns Contents
neg = -1
For Each Cel As DataGridViewCell In GridRow.Cells
neg = neg + 1
If neg < unwantedColsFromStartingPos Then
Continue For
End If
If Cel.Value IsNot Nothing Then
e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font, New SolidBrush(Cel.InheritedStyle.ForeColor), New RectangleF(CInt(arrColumnLefts(iCount)), CSng(iTopMargin), CInt(arrColumnWidths(iCount)), CSng(iCellHeight)), strFormat)
End If
'Drawing Cells Borders
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(arrColumnLefts(iCount)), iTopMargin, CInt(arrColumnWidths(iCount)), iCellHeight))
iCount += 1
Next
End If
iRow += 1
iTopMargin += iCellHeight
End While
'If more lines exist, print another page.
If bMorePagesToPrint Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
End Class
Private _gridPrintHelper As New GridViewPrintHelper
Private Sub prntDoc_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles prntDoc.BeginPrint
Try
_gridPrintHelper.BeginPrint(dgvList, 1)
Catch ex As Exception
Utils.LogHandler.HandleError(ex)
End Try
End Sub
Private Sub prntDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles prntDoc.PrintPage
Try
_gridPrintHelper.PrintPage(dgvList, e, 1)
Catch ex As Exception
Utils.LogHandler.HandleError(ex)
End Try
End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Try
'Open the print dialog
Dim printDialog As New PrintDialog()
printDialog.Document = prntDoc
printDialog.UseEXDialog = True
'Get the document
If DialogResult.OK = printDialog.ShowDialog() Then
prntDoc.DocumentName = "Staff List"
prntDoc.Print()
End If
Catch ex As Exception
Utils.LogHandler.HandleError(ex)
End Try
End Sub