在PrintDocument中打印DataGridView

时间:2014-03-22 17:02:03

标签: vb.net

我是vb.net的新手,我和我的团队正在开发一个系统,我们主要使用DataGridView查看来自SQL Server数据库的记录。

这是我的问题,我有两个DataGridViews,其中一个提取ID和学生名称,而另一个提取基于所选的其他DataGridView行的记录(学生的成绩)。我已经可以打印记录但是当我关闭PrintDocument(没有退出表单)并选择另一个学生并在PrintDocument中再次查看时,

它给我一个错误说

"Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

并且出现后续问题,当我有这个代码"cell.RowIndex - 1"时,DatagridView中的第一条记录无法在PrintDocument中打印,当我删除代码中的“ - 1”时,标题变得疯狂,有时它们会变成空白(带边框),有时它们实际上不显示,只显示记录。

这是发生错误的地方:

 e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex - 1) 
    .Cells(cell.ColumnIndex).FormattedValue.ToString, .Font, 
     Brushes.Black, rc, frmt)

这是我的代码:

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    With DataGridView1
        Dim frmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
        frmt.LineAlignment = StringAlignment.Center
        frmt.Trimming = StringTrimming.EllipsisCharacter

        Dim HeaderFont As Font = New Drawing.Font("Times New Roman", 20)
        Dim reportFont As Font = New Drawing.Font("Times New Roman", 14)
        Dim nrmlfnt As Font = New Drawing.Font("Calbiri", 10)
        Dim drawBrush As New SolidBrush(Color.Black)
        Dim blackpen As New Pen(Color.Black, 1)

        e.Graphics.DrawString("First Fruits Christian Academy", HeaderFont, drawBrush, 250, 50)
        e.Graphics.DrawString("Purok 17 Hindangon, Valencia City Bukidnon", reportFont, drawBrush, 245, 80)
        e.Graphics.DrawString("Student Grade", reportFont, drawBrush, 370, 125)
        e.Graphics.DrawString("Name: " & txtName.Text & "", nrmlfnt, drawBrush, 100, 180)
        e.Graphics.DrawString("Gender: " & txtGender.Text & "", nrmlfnt, drawBrush, 600, 180)
        e.Graphics.DrawString("Grade & Section: " & cboYearLevel.Text & " - " & cboSection.Text & "", nrmlfnt, drawBrush, 100, 200)

        Dim y As Single = e.MarginBounds.Top + 125
        Do While mRow < .RowCount
            Dim row As DataGridViewRow = .Rows(mRow)
            Dim x As Single = e.MarginBounds.Left
            Dim h As Single = 0
            For Each cell As DataGridViewCell In row.Cells
                Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width - 20, cell.Size.Height)
                e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
                    If (newpage) Then
                        e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, frmt)
                    Else
                    e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString, .Font, Brushes.Black, rc, frmt)
                    End If
                x += rc.Width
                h = Math.Max(h, rc.Height)
            Next
            newpage = False
            y += h
            mRow += 1
            If y + h > e.MarginBounds.Bottom Then
                e.HasMorePages = True
                newpage = True
                Exit Sub
            End If
        Loop
        mRow = 0
    End With
End Sub

3 个答案:

答案 0 :(得分:1)

DataGridView打印内容的最佳方法是将每行的集合转换为List(Of String),使用String.Format将值连接在一起。将类变量用于列表中的位置以继续下一页。

Private index As Integer
Private Sub Print(...) Handles PrintDocument1.PrintPage
   Dim row As Integer = {some point you want to start at}
  'Paint a title - since this event fires for each page
  'continue loop or start loop
  For i As Integer = index To myList.Count - 1
   If Not row = e.MarginBounds.Bottom - 12 Then
    'remember where we are in the list
    index = i
    'paint your contents
   Else
    'start new page
    e.HasMorePages = True
    Exit Sub
   End If
  Next
  'reset the index for next print job
  If Not e.HasMorePages Then index = 0 
 End Sub

Dim myList As New List (Of String)
For Each row In dgv.Rows
  'add what data you want to print
Next

答案 1 :(得分:0)

您可能需要从此代码

中删除Else部分
If (newpage) Then
    e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, frmt)
Else
    e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString, .Font, Brushes.Black, rc, frmt)
End If

并将其更改为,

If (newpage) Then
    e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, frmt)
End If
' and at this point you should re-calculate your rectangle again
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString, .Font, Brushes.Black, rc, frmt)

关键是,在每次迭代时,您必须打印行,因此如果newpage标志为true,则表示您只需要在打印行之前先打印标题。 / p>

答案 2 :(得分:-1)

我并证明您的代码有效,现在的问题是服务器提供最后一行数据。 我进行了更改以使其工作:

Dim NewPage As Boolean 
  NewPage = True 

  If (NewPage) = True Then 
    e.Graphics.DrawString (FDesempeño.DataGridView1.Columns (cell.ColumnIndex) .HeaderText, .font, Brushes.Black, rc, frmt) 
 
else 
  e.Graphics.DrawString (FDesempeño.DataGridView1.Rows (cell.RowIndex - 1) .Cells (cell.ColumnIndex) .FormattedValue.ToString, .font, Brushes.Black, rc, frmt) 
End If 

我希望你找到了服务,顺便说一下,我是新手,就像你一样。如果你能纠正错误我可以通过电子邮件联系我们,我的电子邮件是pablo_buy@hotmail.com