tiehaze
asked on
Printing a datagridview in vb.net
I am trying to set up a menu button to print 'datagridview1'. I got the following code from another website, but I am not sure how to call it. This is driving me nuts, can someone help me out?
Private oStringFormat As StringFormat
Private oStringFormatComboBox As StringFormat
Private oButton As Button
Private oCheckbox As CheckBox
Private oComboBox As ComboBox
Private nTotalWidth As Int16
Private nRowPos As Int16
Private NewPage As Boolean
Private nPageNo As Int16
Private Header As String = "Header Test"
Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint( ByVal sender As Object, ByVal e As System.Drawing.Printing.Pr intEventAr gs) Handles PrintDocument1.BeginPrint
oStringFormat = New StringFormat
oStringFormat.Alignment = StringAlignment.Near
oStringFormat.LineAlignmen t = StringAlignment.Center
oStringFormat.Trimming = StringTrimming.EllipsisCha racter
oStringFormatComboBox = New StringFormat
oStringFormatComboBox.Line Alignment = StringAlignment.Center
oStringFormatComboBox.Form atFlags = StringFormatFlags.NoWrap
oStringFormatComboBox.Trim ming = StringTrimming.EllipsisCha racter
oButton = New Button
oCheckbox = New CheckBox
oComboBox = New ComboBox
nTotalWidth = 0
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nTotalWidth += oColumn.Width
Next
nPageNo = 1
NewPage = True
nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(B yVal sender As Object, ByVal e As System.Drawing.Printing.Pr intPageEve ntArgs) Handles PrintDocument1.PrintPage
Static oColumnLefts As New ArrayList
Static oColumnWidths As New ArrayList
Static oColumnTypes As New ArrayList
Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16
Dim nTop As Int16 = e.MarginBounds.Top
Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nWidth = CType(Math.Floor(oColumn.W idth / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(o Column.Hea derText, oColumn.InheritedStyle.Fon t, nWidth).Height + 11
oColumnLefts.Add(nLeft)
oColumnWidths.Add(nWidth)
oColumnTypes.Add(oColumn.G etType)
nLeft += nWidth
Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos )
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True
nPageNo += 1
e.HasMorePages = True
Exit Sub
Else
If NewPage Then
' Draw Header
e.Graphics.DrawString(Head er, New Font(DataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(H eader, New Font(DataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Heig ht - 13)
' Draw Columns
nTop = e.MarginBounds.Top
i = 0
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
e.Graphics.FillRectangle(N ew SolidBrush(Drawing.Color.L ightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawRectangle(P ens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawString(oCol umn.Header Text, oColumn.InheritedStyle.Fon t, New SolidBrush(oColumn.Inherit edStyle.Fo reColor), New RectangleF(oColumnLefts(i) , nTop, oColumnWidths(i), nHeight), oStringFormat)
i += 1
Next
NewPage = False
End If
nTop += nHeight
i = 0
For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBo xColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkCo lumn) Then
e.Graphics.DrawString(oCel l.Value.To String, oCell.InheritedStyle.Font, New SolidBrush(oCell.Inherited Style.Fore Color), New RectangleF(oColumnLefts(i) , nTop, oColumnWidths(i), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButton Column) Then
oButton.Text = oCell.Value.ToString
oButton.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(oButton.Width, oButton.Height)
oButton.DrawToBitmap(oBitm ap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
e.Graphics.DrawImage(oBitm ap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckB oxColumn) Then
oCheckbox.Size = New Size(14, 14)
oCheckbox.Checked = CType(oCell.Value, Boolean)
Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight)
Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap )
oTempGraphics.FillRectangl e(Brushes. White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
oCheckbox.DrawToBitmap(oBi tmap, New Rectangle(CType((oBitmap.W idth - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height))
e.Graphics.DrawImage(oBitm ap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboB oxColumn) Then
oComboBox.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height)
oComboBox.DrawToBitmap(oBi tmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
e.Graphics.DrawImage(oBitm ap, New Point(oColumnLefts(i), nTop))
e.Graphics.DrawString(oCel l.Value.To String, oCell.InheritedStyle.Font, New SolidBrush(oCell.Inherited Style.Fore Color), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageC olumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)
Dim oImageSize As Size = CType(oCell.Value, Image).Size
e.Graphics.DrawImage(oCell .Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(P ens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1
Next
End If
nRowPos += 1
nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.Pr intPageEve ntArgs, ByVal RowsPerPage As Int32)
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1 .Rows.Coun t / RowsPerPage).ToString
' Right Align - User Name
e.Graphics.DrawString(sUse rName, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(s PageNo, DataGridView1.Font, e.MarginBounds.Width).Widt h), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time
e.Graphics.DrawString(Now. ToLongDate String + " " + Now.ToShortTimeString, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info
e.Graphics.DrawString(sPag eNo, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(s PageNo, DataGridView1.Font, e.MarginBounds.Width).Widt h) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub
I want to set it up in the following event:
Private Sub SelectedSecuritysDividendI nformation ToolStripM enuItem_Cl ick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectedSecuritysDividendI nformation ToolStripM enuItem.Cl ick
End Sub
Private oStringFormat As StringFormat
Private oStringFormatComboBox As StringFormat
Private oButton As Button
Private oCheckbox As CheckBox
Private oComboBox As ComboBox
Private nTotalWidth As Int16
Private nRowPos As Int16
Private NewPage As Boolean
Private nPageNo As Int16
Private Header As String = "Header Test"
Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint(
oStringFormat = New StringFormat
oStringFormat.Alignment = StringAlignment.Near
oStringFormat.LineAlignmen
oStringFormat.Trimming = StringTrimming.EllipsisCha
oStringFormatComboBox = New StringFormat
oStringFormatComboBox.Line
oStringFormatComboBox.Form
oStringFormatComboBox.Trim
oButton = New Button
oCheckbox = New CheckBox
oComboBox = New ComboBox
nTotalWidth = 0
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nTotalWidth += oColumn.Width
Next
nPageNo = 1
NewPage = True
nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(B
Static oColumnLefts As New ArrayList
Static oColumnWidths As New ArrayList
Static oColumnTypes As New ArrayList
Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16
Dim nTop As Int16 = e.MarginBounds.Top
Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nWidth = CType(Math.Floor(oColumn.W
nHeight = e.Graphics.MeasureString(o
oColumnLefts.Add(nLeft)
oColumnWidths.Add(nWidth)
oColumnTypes.Add(oColumn.G
nLeft += nWidth
Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True
nPageNo += 1
e.HasMorePages = True
Exit Sub
Else
If NewPage Then
' Draw Header
e.Graphics.DrawString(Head
' Draw Columns
nTop = e.MarginBounds.Top
i = 0
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
e.Graphics.FillRectangle(N
e.Graphics.DrawRectangle(P
e.Graphics.DrawString(oCol
i += 1
Next
NewPage = False
End If
nTop += nHeight
i = 0
For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBo
e.Graphics.DrawString(oCel
ElseIf oColumnTypes(i) Is GetType(DataGridViewButton
oButton.Text = oCell.Value.ToString
oButton.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(oButton.Width, oButton.Height)
oButton.DrawToBitmap(oBitm
e.Graphics.DrawImage(oBitm
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckB
oCheckbox.Size = New Size(14, 14)
oCheckbox.Checked = CType(oCell.Value, Boolean)
Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight)
Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap
oTempGraphics.FillRectangl
oCheckbox.DrawToBitmap(oBi
e.Graphics.DrawImage(oBitm
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboB
oComboBox.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height)
oComboBox.DrawToBitmap(oBi
e.Graphics.DrawImage(oBitm
e.Graphics.DrawString(oCel
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageC
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i),
Dim oImageSize As Size = CType(oCell.Value, Image).Size
e.Graphics.DrawImage(oCell
End If
e.Graphics.DrawRectangle(P
i += 1
Next
End If
nRowPos += 1
nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.Pr
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1
' Right Align - User Name
e.Graphics.DrawString(sUse
' Left Align - Date/Time
e.Graphics.DrawString(Now.
' Center - Page No. Info
e.Graphics.DrawString(sPag
End Sub
I want to set it up in the following event:
Private Sub SelectedSecuritysDividendI
End Sub
Very simple:
Private Sub SelectedSecuritysDividendI nformation ToolStripM enuItem_Cl ick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectedSecuritysDividendI nformation ToolStripM enuItem.Cl ick
PrintDocument1.Print()
End Sub
Private Sub SelectedSecuritysDividendI
PrintDocument1.Print()
End Sub
BTW, before calling "print" you can set your printing settings (like printer name, paper size, paper source, etc) up. For ex:
Private Sub SelectedSecuritysDividendI nformation ToolStripM enuItem_Cl ick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectedSecuritysDividendI nformation ToolStripM enuItem.Cl ick
PrintDocument1.PrinterSett ings.Print erName = "your printer"
PrintDocument1.Print()
End Sub
Private Sub SelectedSecuritysDividendI
PrintDocument1.PrinterSett
PrintDocument1.Print()
End Sub
ASKER
VBRocks,
Yes, all of the data will be visible on the datagridview, and will always be from the same datasource
Yes, all of the data will be visible on the datagridview, and will always be from the same datasource
Ok, 2 approaches then.
1. If all of the data in the datagridview will always be visible at the same time on the form, then you
can just print out the form, which is pretty easy.
2. An alternative approach, that I prefer, is if you have VS Pro., then you can create a Crystal
Report and print your data from that.
Does either of those sound appealing to you? They both are probably a bit easier.
1. If all of the data in the datagridview will always be visible at the same time on the form, then you
can just print out the form, which is pretty easy.
2. An alternative approach, that I prefer, is if you have VS Pro., then you can create a Crystal
Report and print your data from that.
Does either of those sound appealing to you? They both are probably a bit easier.
ASKER
How do you print out the form?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I've got the following error:
Private Sub SelectedSecuritysDividendI nformation ToolStripM enuItem_Cl ick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectedSecuritysDividendI nformation ToolStripM enuItem.Cl ick
PrintDocument1.PrintPage()
End Sub
The error is telling me that PrintDocument1 is not declared. Am I missing something?
Private Sub SelectedSecuritysDividendI
PrintDocument1.PrintPage()
End Sub
The error is telling me that PrintDocument1 is not declared. Am I missing something?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Worked Perfect... thanks!
Once question, within the datagridview, there are columns with dates. As of right now, it is printing the date in the following format:
6/6/2007
12:00:00 AM
How do I get it to show the date, not the date & time
Once question, within the datagridview, there are columns with dates. As of right now, it is printing the date in the following format:
6/6/2007
12:00:00 AM
How do I get it to show the date, not the date & time
That has to do with the way you have your column formatted, and is off track from the printing question.
But let me explain how you can change that:
If you go to your form in design view, click on your datagridview, then go to properties, click on the
Columns property, then click the "..." button, it will open a "Edit Columns" window. On the left, click on
the column that is the date column. Then find the DefaultCellStyle property, click on it, then click on
the "..." button to open the CellStyle Builder window. Click on the Format property, then on the "..."
button to open the Format String Dialog window. Select DateTime on the left, then the format Type on
the right.
But let me explain how you can change that:
If you go to your form in design view, click on your datagridview, then go to properties, click on the
Columns property, then click the "..." button, it will open a "Edit Columns" window. On the left, click on
the column that is the date column. Then find the DefaultCellStyle property, click on it, then click on
the "..." button to open the CellStyle Builder window. Click on the Format property, then on the "..."
button to open the Format String Dialog window. Select DateTime on the left, then the format Type on
the right.
tiehaze, Did you have any other questions as far as the printing is concerned? or is it ok to close the
question?
question?
ASKER
Sorry, I will wrap up on that question right now
ASKER
Haha, it is this question... one sec
Thanks tiehaze!
1. Will your datagridview have more data than what is visible on the form?
2. Does your datagridview always display the same datasource?