Here's a little something to get you started - taken strait from a production app:
Code:
        Private Sub PrintDataViewGrid(ByRef dgv As Windows.Forms.DataGridView, ByVal PrintArgs As Drawing.Printing.PrintPageEventArgs)

            Dim linesPerPage As Single = 0
            Dim yPos As Single = 0
            Dim iThisPageLineCount As Integer = 0
            Dim iPos, iTotalColWidth, iColHeaderChars, iAvgColHeaderChars As Integer
            Dim leftMargin As Single = PrintArgs.MarginBounds.Left
            Dim topMargin As Single = PrintArgs.MarginBounds.Top
            Dim itmPrint As Windows.Forms.DataGridViewRow
            Dim line As String = Nothing
            Dim sngColumnPositions() As Single
            Dim sfPlain As Drawing.StringFormat, sfCenter As Drawing.StringFormat
            Dim rectLayout As Drawing.RectangleF
            Dim FontBold As Drawing.Font
            Dim Font As Drawing.Font

            'create any string formats and special fonts
            Font = dgv.Font
            sfPlain = New Drawing.StringFormat
            FontBold = New Drawing.Font(Font, Drawing.FontStyle.Bold)

            'calculate the number of lines per page.
            linesPerPage = PrintArgs.MarginBounds.Height / Font.GetHeight(PrintArgs.Graphics)
            'PrintDoc.DefaultPageSettings.Bounds.Height

            For Each c As Windows.Forms.DataGridViewColumn In dgv.Columns
                If c.Visible Then
                    iTotalColWidth += c.Width
                    iColHeaderChars += c.HeaderText.Length
                End If
            Next

            iAvgColHeaderChars = Int(iColHeaderChars / dgv.Columns.Count)

            'determine our column positions
            iPos = leftMargin
            ReDim sngColumnPositions(dgv.Columns.Count - 1)
            For Each c As Windows.Forms.DataGridViewColumn In dgv.Columns
                If c.Visible Then
                    sngColumnPositions(c.Index) = iPos
                    iPos += PrintArgs.MarginBounds.Width * (c.Width / iTotalColWidth)
                Else
                    sngColumnPositions(c.Index) = iPos
                End If
            Next


            'add the page header, if any
            If Me.m_PageTitle.Length > 0 Then
                sfCenter = New Drawing.StringFormat
                sfCenter.Alignment = Drawing.StringAlignment.Center
                rectLayout = New Drawing.RectangleF(PrintArgs.MarginBounds.Left, PrintArgs.MarginBounds.Top, PrintArgs.MarginBounds.Width, Font.GetHeight(PrintArgs.Graphics) * Me.m_PageTitle.Split(vbCrLf).Length)
                PrintArgs.Graphics.DrawString(m_PageTitle, Font, Drawing.Brushes.Black, rectLayout, sfCenter)
                iThisPageLineCount += Me.m_PageTitle.Split(CChar(vbCrLf)).Length
            End If

            'increment one more line to double-space
            iThisPageLineCount += 2

            'determine our y position for this row
            yPos = topMargin + iThisPageLineCount * Font.GetHeight(PrintArgs.Graphics)
            'yPos = topMargin + dgv.ColumnHeadersHeight
            For Each c As Windows.Forms.DataGridViewColumn In dgv.Columns
                If c.Visible Then

                    If c.Index < sngColumnPositions.Length - 1 Then
                        rectLayout = New Drawing.RectangleF(sngColumnPositions(c.Index), yPos, sngColumnPositions(c.Index + 1) - sngColumnPositions(c.Index), dgv.ColumnHeadersHeight + iAvgColHeaderChars)
                    Else
                        rectLayout = New Drawing.RectangleF(sngColumnPositions(c.Index), yPos, PrintArgs.MarginBounds.Right - sngColumnPositions(c.Index), dgv.ColumnHeadersHeight + iAvgColHeaderChars)
                    End If
                    sfPlain.LineAlignment = Drawing.StringAlignment.Far
                    PrintArgs.Graphics.DrawString(c.HeaderCell.Value.ToString, Font, Drawing.Brushes.Black, rectLayout, sfPlain)
                    'PrintArgs.Graphics.DrawString(c.HeaderCell.Value, fntBold, Drawing.Brushes.Black, sngColumnPositions(c.Index), yPos, sfPlain)
                End If
            Next
            iThisPageLineCount += 1

            'print each line of the list.
            While iThisPageLineCount < linesPerPage AndAlso m_iPrintIndex < dgv.Rows.Count

                'get this item
                itmPrint = dgv.Rows(m_iPrintIndex)

                'determine our y position for this row
                yPos = topMargin + dgv.ColumnHeadersHeight + iAvgColHeaderChars + iThisPageLineCount * Font.GetHeight(PrintArgs.Graphics)

                'print the cells
                For Each c As Windows.Forms.DataGridViewCell In itmPrint.Cells
                    If c.Visible Then
                        If System.DBNull.Value.Equals(c.Value) Then
                            PrintArgs.Graphics.DrawString(String.Empty, Font, Drawing.Brushes.Black, sngColumnPositions(c.OwningColumn.Index), yPos, sfPlain)
                        ElseIf TypeOf c Is Windows.Forms.DataGridViewCheckBoxCell Then
                            With CType(c, Windows.Forms.DataGridViewCheckBoxCell)
                                If CBool(.FormattedValue) Then
                                    PrintArgs.Graphics.DrawString("X", Font, Drawing.Brushes.Black, sngColumnPositions(c.OwningColumn.Index), yPos + Font.GetHeight(PrintArgs.Graphics), sfPlain)
                                End If
                            End With
                        Else
                            If c.OwningColumn.Index < sngColumnPositions.Length - 1 Then
                                rectLayout = New Drawing.Rectangle(sngColumnPositions(c.OwningColumn.Index), yPos, sngColumnPositions(c.OwningColumn.Index + 1) - sngColumnPositions(c.OwningColumn.Index), Font.GetHeight(PrintArgs.Graphics))
                            Else
                                rectLayout = New Drawing.Rectangle(sngColumnPositions(c.OwningColumn.Index), yPos, PrintArgs.MarginBounds.Right - sngColumnPositions(c.OwningColumn.Index), Font.GetHeight(PrintArgs.Graphics))
                            End If
                            PrintArgs.Graphics.DrawString(c.FormattedValue, Font, Drawing.Brushes.Black, rectLayout, sfPlain)
                        End If
                    End If
                Next

                'increment the print counter
                'and persist it to the print index
                iThisPageLineCount += 1
                m_iPrintIndex += 1

            End While

            ' if more lines exist, print another page.
            PrintArgs.HasMorePages = m_iPrintIndex < dgv.Rows.Count

        End Sub
NOTE: This .net version 2.0 - there may be better ways in newer versions. I know this works, though.