简体   繁体   English

在PrintDocument中打印DataGridView

[英]Printing DataGridView in PrintDocument

I am a new to vb.net, I with my team are developing a system where we dominantly use DataGridView in viewing our records from SQL Server database. 我是vb.net的新手,我和我的团队一起在开发一个系统,在该系统中,我们主要使用DataGridView来查看SQL Server数据库中的记录。

Here's my problem, i have two DataGridViews where one extracts the ID and Student name while the other one extracts records(grades of the student) based on the other DataGridView row selected. 这是我的问题,我有两个DataGridViews,其中一个提取ID和学生姓名,而另一个则根据所选的另一个DataGridView行提取记录(学生的成绩)。 I can already print the records but when i close the PrintDocument(without exiting the form) and choose another student and view it again in PrintDocument, 我已经可以打印记录了,但是当我关闭PrintDocument(不退出表单)并选择另一个学生并在PrintDocument中再次查看它时,

it gives me an error saying 这给我一个错误的说法

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

and a follow-up problem occurs, when i have this code "cell.RowIndex - 1" , the first record in the DatagridView can't be printed in the PrintDocument and when i erase the "- 1" in the code, the header goes crazy, sometimes they go blank(w/ borders) and sometimes they really do not display, only the records are displayed. 并且出现后续问题,当我有此代码"cell.RowIndex - 1" ,无法在PrintDocument中打印DatagridView中的第一条记录,而当我擦除代码中的“-1”时,标题变得疯狂,有时它们变成空白(带有边框),有时它们实际上不显示,仅显示记录。

this is where the error occurs: 这是发生错误的地方:

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

This is my code: 这是我的代码:

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

The best way to print things from a DataGridView is to make a collection of each row into a List(Of String) making use of String.Format to concatenate the values together. DataGridView打印内容的最佳方法是利用String.Format将值连接在一起,将每一行的集合放入List(Of String) Use a class variable for where in the list you are at for the next pages to continue. 将类变量用于列表中的位置,以使下一页继续。

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

Probably you need to remove the Else part from this code, 可能您需要从此代码中删除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

And change it to, 并将其更改为

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)

The point is, on each iteration, you have to print the row , so if the newpage flag is true then it means you just need to print the header first before you print the line. 关键是, 在每次迭代中,您都必须打印该行 ,因此,如果newpage标志为true,则意味着您只需要在打印该行之前首先打印标题即可。

me and prove your code worked, now the problem is that servers provide last row of data. 我并证明您的代码有效,现在的问题是服务器提供了最后一行数据。 I made changes to make it work are: 我进行了更改以使其起作用:

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 

I hope you found served, by the way I am newbie like you. 希望您能像我一样成为新手,找到服务。 if you can correct the error if I agradesericia you can contact us by email, my email is pablo_buy@hotmail.com 如果您可以纠正错误(如果我是agradesericia),则可以通过电子邮件与我们联系,我的电子邮件为pablo_buy@hotmail.com

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM