Vb.net 在PrintDocument中打印DataGridView

Vb.net 在PrintDocument中打印DataGridView,vb.net,Vb.net,我是vb.net的新手,我和我的团队正在开发一个系统,我们主要使用DataGridView从SQL Server数据库查看记录 这是我的问题,我有两个DataGridView,其中一个提取ID和学生姓名,而另一个提取基于另一个选定DataGridView行的记录(学生的成绩)。我已经可以打印记录,但当我关闭PrintDocument(不退出表单)并选择另一名学生并在PrintDocument中再次查看时 这给了我一个错误的说法 “索引超出范围。必须为非负数且小于集合的大小。”。 参数名称:索引“

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

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

这给了我一个错误的说法

“索引超出范围。必须为非负数且小于集合的大小。”。
参数名称:索引“

随后出现了一个问题,当我有这个代码时,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
Private Sub PrintDocument1\u PrintPage(ByVal sender作为System.Object,ByVal e作为System.Drawing.Printing.PrintPageEventArgs)处理PrintDocument1.PrintPage
使用DataGridView1
作为StringFormat的Dim frmt=新StringFormat(StringFormatFlags.LineLimit)
frmt.LineAlignment=StringAlignment.Center
frmt.TRIMING=STRINGTRIMING.ELLIPSSCHARACTER
暗淡的头部字体为Font=新绘图.Font(“Times New Roman”,20)
Dim reportFont As Font=新绘图.Font(“Times New Roman”,14)
Dim nrmlfnt As Font=新图纸字体(“Calbiri”,10)
与新SolidBrush一样暗淡的drawBrush(颜色:黑色)
暗黑色笔作为新笔(颜色.黑色,1)
e、 图形.抽绳(“First Fruits Christian Academy”,HeaderFont,drawBrush,250,50)
e、 图形.抽绳(“Purok 17 Hindangon,巴伦西亚市Buydonon”,reportFont,drawBrush,24580)
e、 图形.抽绳(“学生成绩”,reportFont,drawBrush,370125)
e、 Graphics.DrawString(“名称:”&txtName.Text&“”,nrmlfnt,drawBrush,100180)
e、 Graphics.DrawString(“性别:&txtGender.Text&”,nrmlfnt,drawBrush,600,180)
e、 Graphics.DrawString(“Grade&Section:&cboYearLevel.Text&-”&cboSection.Text&“”,nrmlfnt,drawsbrush,100200)
尺寸y为单个=e.MarginBounds.Top+125
当mRow<.RowCount时执行
作为DataGridViewRow=.Rows(mRow)的Dim行
尺寸x为单个=e.MarginBounds.Left
尺寸h为单个=0
对于行中的每个单元格作为DataGridViewCell
尺寸rc为矩形F=新矩形F(x,y,cell.Size.Width-20,cell.Size.Height)
e、 图形.绘图矩形(钢笔.黑色,rc.左侧,rc.顶部,rc.宽度,rc.高度)
如果(newpage)那么
e、 Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText、.Font、Brushes.Black、rc、frmt)
其他的
e、 Graphics.DrawString(DataGridView1.Rows(cell.RowIndex-1)、Cells(cell.ColumnIndex)、FormattedValue.ToString、.Font、Brush.Black、rc、frmt)
如果结束
x+=钢筋混凝土宽度
h=数学最大值(h,钢筋混凝土高度)
下一个
newpage=False
y+=h
mRow+=1
如果y+h>e.MarginBounds.Bottom,则
e、 HasMorePages=True
newpage=True
出口接头
如果结束
环
mRow=0
以
端接头

DataGridView
打印内容的最佳方法是将每一行的集合制作成
列表(字符串)
使用
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

您可能需要从此代码中删除
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,则意味着您只需在打印行之前先打印页眉。

请验证您的代码是否有效,现在的问题是服务器提供了最后一行数据。 为使其正常工作,我做了以下更改:

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

很抱歉,请告诉我您的代码中的“myList”是什么……谢谢就像我说的,收集您想要打印的内容,这是我真实的版本。不过,一天的方法更合适。