vb.net 在 PrintDocument 中打印 DataGridView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22580715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing DataGridView in PrintDocument
提问by user3450006
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. 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,
这是我的问题,我有两个 DataGridView,其中一个提取 ID 和学生姓名,而另一个根据所选的另一个 DataGridView 行提取记录(学生的成绩)。我已经可以打印记录,但是当我关闭 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"
"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
回答by OneFineDay
The best way to print things from a DataGridViewis to make a collection of each row into a List(Of String)making use of String.Formatto concatenate the values together. Use a class variable for where in the list you are at for the next pages to continue.
从 a 打印事物的最佳方法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
回答by sallushan
Probably you need to remove the Elsepart 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.
关键是,在每次迭代中,您必须打印 row,因此如果 newpage 标志为真,则意味着您只需要在打印行之前先打印标题即可。
回答by pablo
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 [email protected]
我希望你能找到服务,顺便说一下,我和你一样是新手。如果您可以更正错误,如果我是 agradesericia 您可以通过电子邮件与我们联系,我的电子邮件是 [email protected]

