How to print DataGridView data? - vb.net

Here is my code to Print:
Private Sub btnPrint_Click(sender As System.Object, e As System.EventArgs) Handles btnPrint.Click
PrintInvoiceDoc.DefaultPageSettings.Landscape = True
PrintPreviewDialog.ShowDialog()
End Sub
Private Sub PrintInvoiceDoc_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintInvoiceDoc.PrintPage
Dim CenterAlign As New StringFormat
CenterAlign.Alignment = StringAlignment.Center
Dim RightAlign As New StringFormat
CenterAlign.Alignment = StringAlignment.Far
e.Graphics.DrawString("School Name", New Font("Arial", 16, FontStyle.Bold), Brushes.Black, New Point(25, 25))
e.Graphics.DrawString("Report", New Font("Arial", 16, FontStyle.Bold), Brushes.Black, New Point(1000, 25), RightAlign)
Dim mRow As Integer = 0
Dim newpage As Boolean = True
With DataGridView1
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top
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, 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, fmt)
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
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
mRow -= 1
newpage = True
Exit Sub
End If
Loop
mRow = 0
End With
End Sub
So, when hit 'Print' I get the result shown in this image:
Problem #1: I am missing the first row [As you can see]
Problem #2: When the rows are enough that one page is not enough to store all of them, new page is created in infinite loop and same page is repeated so not all data is printed.
Note: I almost don't have any idea about using a DataGridView in PrintDocument, but any advice/tips are welcome!

ur first row behind header row... make new rectanglef for ur header row like this....
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
Dim rc2 As RectangleF = New RectangleF(x, y - 22, cell.Size.Width, cell.Size.Height)
If (newpage) Then
e.Graphics.FillRectangle(New SolidBrush(Color.LightGray), New RectangleF(x, y - 22, cell.Size.Width, cell.Size.Height))
e.Graphics.DrawRectangle(Pens.Black, rc2.Left, rc2.Top, rc2.Width, rc2.Height)
e.Graphics.DrawString(dgpembelian.Columns(cell.ColumnIndex).HeaderText, cellheaderFont, Brushes.Black, rc2, drawFormat)
End If
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
e.Graphics.DrawString(dgpembelian.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString, .Font, Brushes.Black, rc, drawFormat)
x += rc.Width
h = Math.Max(h, rc.Height)
Next

Related

Adding empty rows and empty columns when printing a report in Datagridview

I want to print a list of students in a class. My columns are things like admno,sname,gender and class(e.g form 1B,1G,2B,2G etc).
The code I use only print the available values from a dgv using the rectangle object.
To draw the rectangle and print the dgv I import System.Drawing.Printing
With the following event handling.
My question is how to add empty rows and empty columns until the page is full, just to allow that printed page to be filled manually with a pen.
Dim i As Integer = 0
Dim newpage As Boolean = True
Dim WithEvents PrintDoc As New PrintDocument
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Dim psd As New PageSetupDialog
psd.Document = PrintDoc
If psd.ShowDialog() <> Windows.Forms.DialogResult.OK Then Exit Sub
Dim ppvw As New PrintPreviewDialog
ppvw.Document = PrintDoc
If ppvw.ShowDialog() <> Windows.Forms.DialogResult.OK Then Exit Sub
PrintDoc.Print()
End Sub
Private Sub PrintDoc_BeginPrint(ByVal sender As Object, ByVal e As PrintEventArgs) Handles PrintDoc.BeginPrint
i = 0
newpage = True
End Sub
Private Sub PrintDoc_PrintPage(ByVal sender As System.Object, ByVal e As PrintPageEventArgs) Handles PrintDoc.PrintPage
' sets it to show '...' for long text
Dim format As New StringFormat(StringFormatFlags.LineLimit)
format.Alignment = StringAlignment.Near
format.Trimming = StringTrimming.EllipsisCharacter
Dim rc As Rectangle
Dim x As Int32 = e.MarginBounds.Left
Dim y As Int32 = e.MarginBounds.Top
Dim h As Int32
Dim row As DataGridViewRow
'print the header text for a new page, use a grey BG just like the control
If newpage Then
row = dgv.Rows(i)
For Each cell As DataGridViewCell In row.Cells
If cell.Visible Then
rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.FillRectangle(Brushes.LightGray, rc)
e.Graphics.DrawRectangle(Pens.Black, rc)
e.Graphics.DrawString(dgv.Columns(cell.ColumnIndex).HeaderText, dgv.Font, Brushes.Black, rc, format)
x += rc.Width
h = Math.Max(h, rc.Height)
End If
Next
y += h
End If
newpage = False
'now print the data for each row
For index As Int32 = i To dgv.RowCount - 1
'no need to try to print the new row
If dgv.Rows(index).IsNewRow Then Exit For
row = dgv.Rows(index)
x = e.MarginBounds.Left
h = 0
'reset X for data
x = e.MarginBounds.Left
' print the data
For Each cell As DataGridViewCell In row.Cells
If cell.Visible Then
rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc)
e.Graphics.DrawString(cell.FormattedValue.ToString(), dgv.Font, Brushes.Black, rc, format)
x += rc.Width
h = Math.Max(h, rc.Height)
End If
Next
y += h
'next row to print
i = index + 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
newpage = True
Return
End If
Next
End Sub

VB.NET - how to add a title on top of printed page in datagridview?

I have a windows application on VB.net 2010 and a datagridview inside,
all works fine and the printing also, but I would like to add a Title on the printed page! from textbox that I have, is it possible?
Please replay as soon as you can, and this is my PrintDocument code attached!
With DataGridView1
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top
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, 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, fmt)
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
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
mRow -= 1
newpage = True
Exit Sub
End If
Loop
mRow = 0
End With
And also, can I adjust the space from the top of the page?
Thanx in advance ^^
This code might works , try it . But it is a little bit different from your code.
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
With Printer
Printer.Title = "Your Title" 'You can change this by TextBox1.text
Printer.SubTitle = "Your Subtitle" 'You can change this by TextBox2.text
Printer.SubTitleFormatFlags = StringFormatFlags.LineLimit Or _
StringFormatFlags.NoClip
Printer.PageNumbers = True
Printer.PageNumberInHeader = False
Printer.PorportionalColumns = True
Printer.HeaderCellAlignment = StringAlignment.Near
Printer.Footer = "Your Footer"
Printer.FooterSpacing = 15
Printer.PrintDataGridView(Me.DataGridView1)
End With
End Sub
If the above code doesn't work , you can try this one.
Private PrintGrid As DataGridViewPrint
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Dim fpr As New frmPrint()
With fpr
.Title = DataGridView1.CaptionText
.ShowDialog()
If .Result > 0 Then
PrintGrid = New DataGridViewPrint(PrintDocument1, DataGridView1, .bBlackWhite)
PrintGrid.PrintTitle = .bTitle
PrintGrid.Title = .Title
Select Case .Result
Case 1 ' Print
' The Print method prints the DataGridView without using a print dialog.
' Use a PrintDialog when you want to offer the user the ability to choose print settings.
If PrintDialog1.ShowDialog() = DialogResult.OK Then PrintDocument1.Print()
Case 2 ' Page Setup
PageSetupDialog1.ShowDialog()
Case 3 ' Preview
PrintPreviewDialog1.Icon = fpr.Icon
PrintPreviewDialog1.ShowDialog()
End Select
End If
End With
End Sub
' Specify the output to print by handling the PrintPage event
' and by using the Graphics included in the PrintPageEventArgs.
Private Sub printDocument1_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
' Print method of DataGridViewPrint class starts the custom DataGridView's printing process.
e.HasMorePages = PrintGrid.Print(e.Graphics)
End Sub
I've found this solution useful!
Try to add this into Printducoment method:
' Create string to draw.
Dim drawString As [String] = "Sample Text"
' Create font and brush.
Dim drawFont As New Font("Arial", 16)
Dim drawBrush As New SolidBrush(Color.Black)
' Create rectangle for drawing.
Dim x As Single = 150.0F
Dim y As Single = 150.0F
Dim width As Single = 200.0F
Dim height As Single = 50.0F
Dim drawRect As New RectangleF(x, y, width, height)
' Draw rectangle to screen.
Dim blackPen As New Pen(Color.Black)
e.Graphics.DrawRectangle(blackPen, x, y, width, height)
' Set format of string.
Dim drawFormat As New StringFormat
drawFormat.Alignment = StringAlignment.Center
' Draw string to screen.
e.Graphics.DrawString(drawString, drawFont, drawBrush, _
drawRect, drawFormat)
And it worked just fine as drawing a text on top of my Datagrideview page ^^
Thanks 'mark ashraf' for your answers <3

Cannot get information on preview print from datagridview

Im using this cod to try to preview my print from datagridview:
Dim mRow As Integer = 0
Dim newpage As Boolean = True
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim custCells As Integer() = {1, 2, 3, 4, 5}
With DataGridView1
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top
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 Integer In custCells
Dim rc As RectangleF = New RectangleF(x, y, row.Cells(cell).Size.Width, row.Cells(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).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(DataGridView1.Rows(row.Cells(cell).RowIndex).Cells(cell).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
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
mRow -= 1
newpage = True
Exit Sub
End If
Loop
mRow = 0
End With
End Sub
The thing is, when i try to preview, the information of my datagridview doesnt show on the preview, only the column names.
Some help?
Thank you!

Save Draw String or e.graphic as image

NEED HELP PLEASE ! Saving Picture with ""Drawstring, e.graphic""
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim Bmp As New Bitmap(Width, Height)
Dim objBitmap As New Bitmap(Width, Height)
objBitmap.Save("c:\Prompter\checking2.TIFF")
Dim g As Graphics = Graphics.FromImage(Bmp)
Dim cx As Integer = Width
Dim cy As Integer = Height
Dim pen As New Pen(Color.Black)
Dim rect As New Rectangle(0, 0, Width, Height)
Dim drawFormat As New StringFormat()
drawFormat.Alignment = StringAlignment.Center
drawFormat.LineAlignment = StringAlignment.Center
Dim stringFont As New Font("Arial", 50)
g.DrawString(RichTextBox1.Text, stringFont, New SolidBrush(Color.White), rect, drawFormat)
Bmp.Save("c:\Prompter\checking2.TIFF", Imaging.ImageFormat.Tiff)
Using bmp2 As New Drawing.Bitmap(Width, Height)
DrawToBitmap(Bmp, New Rectangle(0, 0, Bmp.Width, Bmp.Height))
Bmp.Save("c:\Prompter\screenshoot.bmp")
End Using
End Sub
Not saving Picture just BLANK Image is showing !
Try disposing graphics before save ..
g.Dispose()
Bmp.Save("c:\Prompter\checking2.TIFF", Imaging.ImageFormat.Tiff)

Visual Basic - draw a random number of the same size circles (5 – 10) across the form each in random color using a loop

I have this code that I wrote up, but this code was used when I left clicked on the form, but wasn't a random number of circles. I am wondering how I can adapt it to draw 5-10 random circles with random colors across the form when I click a button, but it has to use a loop. Thanks!!
Private Sub CirclePainterForm_MouseDown(ByVal sender As _
Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseDown
Dim graphicsObject As Graphics = CreateGraphics()
Dim randomObject As Random = New Random
Dim diameter As Integer = randomObject.Next(5, 200)
If e.Button = Windows.Forms.MouseButtons.Left Then
graphicsObject.FillEllipse(New SolidBrush(RandomColor()), e.X, e.Y, _
diameter, diameter)
graphicsObject.FillEllipse(New SolidBrush(RandomColor()), e.X + 250, e.Y, _
diameter + 50, diameter + 50)
graphicsObject.FillEllipse(New SolidBrush(RandomColor()), e.X + 500, e.Y, _
diameter + 75, diameter + 75)
graphicsObject.FillEllipse(New SolidBrush(RandomColor()), e.X + 750, e.Y, _
diameter + 100, diameter + 100)
graphicsObject.FillEllipse(New SolidBrush(RandomColor()), e.X + 1000, e.Y, _
diameter + 125, diameter + 125)
Add a button to your form and add code for the Click event:
To do Circles Or Squares [and updated with your/my comments]
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rnd As New Random(), rndCol As New Random(DateTime.Now.Ticks Mod ((rnd.Next) + 1))
Dim numShapes = rnd.Next(5, 11), bIsCircleOrSquare As Boolean = (rnd.Next Mod 2)
Using g = Me.CreateGraphics()
g.Clear(Me.BackColor)
Dim diam = rnd.Next(55, Math.Min(255, ClientSize.Width))
While numShapes > 0
Using b As New SolidBrush(Color.FromArgb(rndCol.Next(100, 256), rndCol.Next(256), rndCol.Next(256), rndCol.Next(256)))
Dim x = rnd.Next(ClientSize.Width - diam), y = rnd.Next(ClientSize.Height - diam)
If bIsCircleOrSquare Then
g.FillRectangle(b, x, y, diam, diam)
g.DrawRectangle(Pens.Black, x, y, diam, diam)
Else
g.FillEllipse(b, x, y, diam, diam)
g.DrawEllipse(Pens.Black, x, y, diam, diam)
End If
End Using
numShapes -= 1
End While
End Using
End Sub
If you want to see the circles overlap you can replace:
Using b As New SolidBrush(Color.FromArgb(rndCol.Next(100,256), rndCol.Next(256), rndCol.Next(256), rndCol.Next(256)))
with
Using b As New SolidBrush(Color.FromArgb(255, rndCol.Next(256), rndCol.Next(256), rndCol.Next(256)))