Hi to all,
I have to preview dataset data using printdoc and my code is below.
Upon clicking the Preview button the preview dialog displays fine with data.
when I close the preview dialog then click the preview button the data is not diplayed.
weird behavior to me.
what should be the cause? Am I missing something?

Private Sub PrintDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument.PrintPage

        Dim PrintAreaHeight, PrintAreaWidth, marginLeft, marginRight, marginTop As Int32
        With PrintDocument.DefaultPageSettings
            ' initializing local variables that contain the bounds of the printing area rectangle
            PrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
            PrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
            ' initializing local variables to hold margin values that will serve
            ' as the X and Y coordinates for the upper left corner of the printing
            ' area rectangle.
            marginLeft = .Margins.Left
            marginRight = .Margins.Right
            marginTop = .Margins.Top
            ' X and Y coordinate
            '.Landscape = True
        End With
        If PrintDocument.DefaultPageSettings.Landscape Then
            Dim intTemp As Int32
            intTemp = PrintAreaHeight
            PrintAreaHeight = PrintAreaWidth
            PrintAreaWidth = intTemp
            ' if the user selects landscape mode, swap the printing area height and width
        End If

        Dim TitleFont As Font = New Font("courier new", 24, FontStyle.Bold Or FontStyle.Underline)
        Dim SubTitleFont As Font = New Font("courier new", 18, FontStyle.Bold)
        Dim SubTitleFont1 As Font = New Font("courier new", 18, FontStyle.Bold Or FontStyle.Underline)
        Dim BodyFont As Font = New Font("courier new", 12, FontStyle.Regular)
        Dim BodyFont1 As Font = New Font("courier new", 14, FontStyle.Bold)

        Dim str As String = "PAYMENTS BY CLASS - " & lblAcadyr.Text

        ' Get Invoice Data:
        Dim InvSql As String
        InvSql = "SELECT StudentID StudID,RollNo No,StudentNames  Student ,Old_New, "
        InvSql += "RegFee Reg,PTAFee PTA,OtherFee Other,TotalFee Total  "
        InvSql += "FROM tblStudents WHERE ClassID =" & cboClasses.Items(cboClasses.SelectedIndex)(0) & " ORDER BY RollNo"
        Dim da As SqlDataAdapter = New SqlDataAdapter(InvSql, Conn)
        Dim ds As New DataSet
        da.Fill(ds, "tblStudents")

        Dim LinesPerPage As Integer = Convert.ToInt32((e.MarginBounds.Height) / BodyFont.GetHeight(e.Graphics)) - 8
        Dim LinesPrinted As Integer = 0

        Static CentresPrinted As Integer = 0
        Static StudentsPrinted As Integer = 0

        Dim X, Y As Integer
        Static pageno As Integer

        X = e.MarginBounds.Left - 50
        Y = e.MarginBounds.Top

        If pageno = 0 Then 'put heading on first page
            'centre the headertext and draw
            Dim Xmid As Integer = Convert.ToSingle(e.PageBounds.Width / 2 - e.Graphics.MeasureString(str, TitleFont).Width / 2)
            e.Graphics.DrawString(str, TitleFont, Brushes.Blue, Xmid, Y)
            Y = Y + 50
            'Get Classname
            Dim Xmid1 As Integer = Convert.ToSingle(e.PageBounds.Width / 2 - e.Graphics.MeasureString("Class - " & cboClasses.Text, SubTitleFont).Width / 2)
            e.Graphics.DrawString("Class - " & cboClasses.Text, SubTitleFont1, Brushes.Blue, Xmid1, Y)
            Y = Y + 50

            'column headers on each page
            e.Graphics.DrawString("StudID", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 120
            e.Graphics.DrawString("No", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 40
            e.Graphics.DrawString("Student", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 190
            e.Graphics.DrawString("   ", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 70
            e.Graphics.DrawString("Reg.", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 80
            e.Graphics.DrawString("PTA", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 70
            e.Graphics.DrawString("Other", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 100
            e.Graphics.DrawString("Total", SubTitleFont, Brushes.Blue, X, Y)

            LinesPrinted = 3
            Y = Y + 20
        Else
            Y = Y - FontHeight - 40   'shift startpoint upwards

            'column headers on each page
            e.Graphics.DrawString("StudID", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 120
            e.Graphics.DrawString("No", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 40
            e.Graphics.DrawString("Student", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 190
            e.Graphics.DrawString("   ", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 70
            e.Graphics.DrawString("Reg.", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 80
            e.Graphics.DrawString("PTA", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 70
            e.Graphics.DrawString("Other", SubTitleFont, Brushes.Blue, X, Y)

            X = X + 100
            e.Graphics.DrawString("Total", SubTitleFont, Brushes.Blue, X, Y)

            LinesPrinted = 3
            Y = Y + 20
        End If


        Dim Xleft As Integer
        Dim FieldValue As String
        Do While (LinesPrinted < LinesPerPage) And (StudentsPrinted <= ds.Tables(0).Rows.Count - 1)
            'body
            Y = Y + FontHeight + 8
            Xleft = e.MarginBounds.Left - 50
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("StudID").ToString
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 120
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("No").ToString
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 40
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("Student").ToString
            If (FieldValue.Length > 17) Then
                FieldValue = FieldValue.Remove(17, FieldValue.Length - 17)
            End If
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 190
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("Old_New").ToString
            If FieldValue = String.Empty Then
                e.Graphics.DrawString("     ", BodyFont, Brushes.Blue, Xleft, Y)
            Else
                e.Graphics.DrawString("[" & FieldValue & "]", BodyFont, Brushes.Blue, Xleft, Y)
            End If

            Xleft = Xleft + 70
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("Reg").ToString
            If FieldValue = String.Empty Then
                FieldValue = "      "
            Else
                FieldValue = CInt(FieldValue).ToString("n0")
            End If
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 80
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("PTA").ToString
            If FieldValue = String.Empty Then
                FieldValue = "      "
            Else
                FieldValue = CInt(FieldValue).ToString("n0")
            End If
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 70
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("Other").ToString
            If FieldValue = String.Empty Then
                FieldValue = "      "
            Else
                FieldValue = CInt(FieldValue).ToString("n0")
            End If
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)

            Xleft = Xleft + 100
            FieldValue = ds.Tables(0).Rows(StudentsPrinted)("Total").ToString
            If FieldValue = String.Empty Then
                FieldValue = "      "
            Else
                FieldValue = CInt(FieldValue).ToString("n0")
            End If
            e.Graphics.DrawString(FieldValue, BodyFont, Brushes.Black, Xleft, Y)


            LinesPrinted = LinesPrinted + 1
            StudentsPrinted = StudentsPrinted + 1
            Y = Y
        Loop
    End Sub
    Private Sub btnPreview_Click(sender As System.Object, e As System.EventArgs) Handles btnPreview.Click
        If cboClasses.Text = String.Empty Then
            MsgBox("Select Class.", MsgBoxStyle.Critical, "")
            Exit Sub
        Else
            With PrintPreviewDialog
                .Document = PrintDocument
                .StartPosition = FormStartPosition.CenterScreen
                .WindowState = FormWindowState.Maximized
                .ShowDialog()
            End With
        End If
    End Sub

Recommended Answers

All 7 Replies

To create a report using PrintDocument I have some opinion, you can use it if you like.

1) Set PrinDocument.DefaultPageSettingsat PrintDocument's BeginPrint event.
2) At the position of With PrintDocument.DefaultPageSettings use With e.PageSettings
3)At line 17 usee.PageSettings.Landscape in lieu of PrintDocument.DefaultPageSettings.Landscape.

Finally, after completion of reporting in my knoledge, you never close the DataSet or DataAdapter. When you 'Click' the Button first time it do it's work and the pointer goes to end of the table. But, 2nd time Dataset and DataAdapter is already opened, so it does not work properly. You can get an error for very next time.
I assume that your report is for a single page. You do not use e.HasMorePages method to print the next page.

In my opinion, What should you do?
Never open the database in PrintPage event. When you try to print repeatedly, you get an error for database or system would be hangged. Take a Two Dimentional Array and store all data in it, in a seperate Sub Procedure. Call the Sub from BeginPrint event. Navigate the Array and print the elements in PrintPage event using Loop.
Hopefully, you can get your result.

Hi Santanu Das
I do have many pages to print so I need e.HasMorePages.
I will appreciate a short example of using arrays in this case.
thanks

I do not understand why are you try to use this condition (LinesPrinted < LinesPerPage) And in Do Loop Statement
At the line No. 189 try to check your pagehight. If your current 'Y' position is grater than is equal to your pageheight then print the pageNo, after that call for new page.

if (Y + FontHeight + 8) >= PrintAreaHeight Then
        'Print Page Number
        pageno +=1
        e.Graphics.DrawString(pagenum, BodyFont, Brushes.Black, Xposition, Yposition)

        'Insert another Page
        e.HasMorePages = True
    EndIf
Loop

'Print the last Page Number
pageno +=1
e.Graphics.DrawString(pagenum, BodyFont, Brushes.Black, Xposition, Yposition)

'Stop to insert Next Page
e.HasMorePages = False

Here is a small sample attachment of what I want.
As a newbie in VB.net an example with statements will help me understand how to use printpage,printpreview dialog,beginprint,endprint,hasmorepages in previewing data from a dataset.
Can someone help me with a simple code for this.
Thanks in advance

Hi; I am sorry for late. I was too busy at my working place.

Now I make a Print Preview Sample for you .
The picture is attached.
ccc428d7f707bf8fdc0d4fb9fe5094cc

Here I take two Radio Buttons for Orientation of the Page and a Print Preview Button on the Form. I also take A Print Document and a Print Preview Dialog Object to show the Print Preview.

The Simple Codification I do for the Printpreview. I tried to make some coments within it for your help.

Imports System
Imports System.Drawing.Printing
Imports System.Text
Imports System.Security.Cryptography


Public Class Form1
    'declaring variables and arrays
    Dim ItmData(999, 3) As String ' A two dimentional array of 1000 rows and 2 columns
    Dim prntRW As Integer
    Dim totAmt As Double

    Dim xpos, ypos As Integer
    Dim qtypos, rtpos As Integer
    Dim pagenum As Integer

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.LoadItemData()
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        PVDlg.Document = PDoc
        PVDlg.ShowDialog()


    End Sub

    Private Sub LoadItemData()
        'Initializing the array elements
        'You also open your database here and initialize the array

        'Here I am taking a for loop to store
        'data in the elements of the array
        'In the Array there are four elements per row
        'In element one I am trying to store the Item Name
        'And element two, three and four are Quantity, Rate and Total Rate respectively(evaluted from Random Value).

        ' Initialize the random-number generator.
        Randomize()

        For i As Integer = 1 To 1000
            'Storing Product Name
            'Here I try to convert the numerical value
            'to Alphanumerical value  as product name using simple encryption method
            'to make a look like original.
            ItmData(i - 1, 0) = ItemName(CStr(i), CStr(i))

            'Storing quantity randomly(range 4 to 14)
            ItmData(i - 1, 1) = CStr(Math.Floor(10 * Rnd()) + 4)

            'Storing Rates randomly(range 10 to 110)
            ItmData(i - 1, 2) = CStr(Format(Math.Round((100 * Rnd()) + 10, 2), "0.00"))

            'Storing Total Amount(i.e. Qty * Rate)
            ItmData(i - 1, 3) = CStr(Format(Val(ItmData(i - 1, 1)) * Val(ItmData(i - 1, 2)), "0.00"))
        Next
    End Sub

    Public Function ItemName(txtkey As String, srkey As String) As String

        Dim hashingFunction As HMACSHA1
        Dim secretKey() As Byte
        Dim hashValue() As Byte
        Dim counter As Integer
        Dim result As String = ""


        ' Try to Prepare the secret key. 
        secretKey = (New UnicodeEncoding).GetBytes((srkey))

        ' Try to Create the hashing component.
        hashingFunction = New HMACSHA1(secretKey, True)

        ' Try to Calculate the hash value.
        hashValue = hashingFunction.ComputeHash((New UnicodeEncoding).GetBytes(txtkey))

        ' Try to Convert to Hex String
        For counter = 0 To (hashValue.Length - 1)
            result &= Hex(hashValue(counter))
        Next counter


        Return result

    End Function


    'PrintDocument BeginPrint event atomatically invoked before when called printPage event.
    Private Sub PDoc_BeginPrint(sender As Object, e As System.Drawing.Printing.PrintEventArgs) Handles PDoc.BeginPrint
        'declaring pagesetting variable
        Dim pgs As New PageSettings

        'Initializing Page Setting values
        pgs.Margins.Top = 25
        pgs.Margins.Bottom = 25
        pgs.Margins.Left = 25
        pgs.Margins.Right = 25

        If RadioButton1.Checked = True Then
            pgs.Landscape = False
        ElseIf RadioButton2.Checked = True Then
            pgs.Landscape = True
        End If
        PDoc.DefaultPageSettings = pgs

        'Initializing row position,Total Amount & Page Number
        prntRW = 0
        totAmt = 0.0#
        pagenum = 0
    End Sub


    Private Sub PDoc_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles PDoc.PrintPage
        'declaring local varibles
        Dim lmg, rmg, tmg, bmg As Integer 'margines of four sides
        Dim pght, pgwd As Integer         'Page height and width
        Dim Arht, Arwd As Integer         'Printable area height and width

        'Declaring Font and size Variables
        Dim txtFont As Font
        Dim txtSize As SizeF

        'initializing local variables to store Page Margins
        With e.PageSettings
            lmg = .Margins.Left
            rmg = .Margins.Right
            tmg = .Margins.Top
            bmg = .Margins.Bottom

            'Take the page height and width as per orientation
            If .Landscape Then
                pght = .PaperSize.Width
                pgwd = .PaperSize.Height
            Else
                pght = .PaperSize.Height
                pgwd = .PaperSize.Width
            End If
        End With

        'initializing the printable height and width
        Arht = pght - tmg - bmg
        Arwd = pgwd - lmg - rmg

        ' Turn on antialias for text to smooth the edge
        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias



        'Printing Headings*******************************************************************

        'Initializing Y-Position
        ypos = tmg + 10

        'Print Heading in the First page
        If pagenum = 0 Then

            'Initializing Font
            txtFont = New Font("Georgia", 16, FontStyle.Bold Or FontStyle.Underline)

            'Initializing Text size

            txtSize = e.Graphics.MeasureString("Report", txtFont)

            xpos = (Arwd - txtSize.Width) / 2
            ypos = tmg + 10
            e.Graphics.DrawString("Stock Statement", txtFont, Brushes.Black, xpos, ypos)

            ypos += txtSize.Height + 10

            'Printing Report Date and Time
            'Initializing Font
            txtFont = New Font("Verdana", 10, FontStyle.Regular)
            txtSize = e.Graphics.MeasureString("Reporting Date : " & Now.Date, txtFont)

            e.Graphics.DrawString("Reporting Date : " & Now.Date, txtFont, Brushes.Black, pgwd - rmg - txtSize.Width, ypos)

            ypos += txtSize.Height
            e.Graphics.DrawString("Reporting Time : " & Format(IIf(Now.Hour > 12, Now.Hour - 12, Now.Hour), "00") & ":" & Format(Now.Minute, "00") & ":" & Format(Now.Second, "00"), txtFont, Brushes.Black, pgwd - rmg - txtSize.Width, ypos)

            ypos += txtSize.Height + 20

            'Draw line
            e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))

            ypos += 3

            'draw headings for details

            'Initializing Font
            txtFont = New Font("Times New Roman", 12, FontStyle.Bold)

            e.Graphics.DrawString("Sl. No.", txtFont, Brushes.Black, lmg, ypos)

            txtSize = e.Graphics.MeasureString("Sl. No.", txtFont)
            xpos = lmg + txtSize.Width + 10
            e.Graphics.DrawString("Product Name", txtFont, Brushes.Black, xpos, ypos)


            txtSize = e.Graphics.MeasureString("Total Value", txtFont)
            xpos = pgwd - rmg - txtSize.Width
            e.Graphics.DrawString("Total Value", txtFont, Brushes.Black, xpos, ypos)

            txtSize = e.Graphics.MeasureString("Rate (Single)", txtFont)
            xpos -= txtSize.Width + 30
            e.Graphics.DrawString("Rate (Single)", txtFont, Brushes.Black, xpos, ypos)
            rtpos = xpos + txtSize.Width - 10

            txtSize = e.Graphics.MeasureString("Quantity", txtFont)
            xpos -= txtSize.Width + 20
            e.Graphics.DrawString("Quantity", txtFont, Brushes.Black, xpos, ypos)
            qtypos = xpos + txtSize.Width - 5

        End If

        'Draw line
        ypos += txtSize.Height
        e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))
        ypos += 2



        'Printing Details*****************************************************************

        'Initializing Font
        txtFont = New Font("Garamond", 12, FontStyle.Regular)

        'Print subtotal of the previous pages at the top of the page
        If pagenum > 0 Then
            txtSize = e.Graphics.MeasureString("C/F....." & CStr(Format(totAmt, "0.00")), txtFont)
            xpos = pgwd - rmg - txtSize.Width - 2
            e.Graphics.DrawString("C/F....." & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)
            ypos += txtSize.Height
        End If

        'Starting the loop
        Do Until prntRW > ItmData.GetUpperBound(0)
            'Print Serial No.
            txtSize = e.Graphics.MeasureString("Sl. No.", txtFont)
            xpos = lmg + txtSize.Width

            txtSize = e.Graphics.MeasureString(CStr(prntRW + 1) & ".", txtFont)
            xpos -= txtSize.Width
            e.Graphics.DrawString(CStr(prntRW + 1) & ".", txtFont, Brushes.Black, xpos, ypos)


            'Print Product Name
            xpos += txtSize.Width + 12
            e.Graphics.DrawString(ItmData(prntRW, 0), txtFont, Brushes.Black, xpos, ypos)



            'Print start from Right Side 
            'for the numerical values to 
            'maintain right alingment

            'Print Total value
            xpos = pgwd - rmg

            txtSize = e.Graphics.MeasureString(ItmData(prntRW, 3), txtFont)
            xpos -= txtSize.Width + 2
            e.Graphics.DrawString(ItmData(prntRW, 3), txtFont, Brushes.Black, xpos, ypos)


            'print Rate per single Item
            txtSize = e.Graphics.MeasureString(ItmData(prntRW, 2), txtFont)
            xpos = rtpos - txtSize.Width
            e.Graphics.DrawString(ItmData(prntRW, 2), txtFont, Brushes.Black, xpos, ypos)

            'print Quantity
            txtSize = e.Graphics.MeasureString(ItmData(prntRW, 1) & " Pcs.", txtFont)
            xpos = qtypos - txtSize.Width
            e.Graphics.DrawString(ItmData(prntRW, 1) & " Pcs.", txtFont, Brushes.Black, xpos, ypos)


            'Adding total values
            totAmt += Val(ItmData(prntRW, 3))
            prntRW += 1
            ypos += txtSize.Height


            If (ypos >= (pght - bmg) - 50) Then

                'Draw Line
                e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))


                'print sub total of current page at bottom position
                txtSize = e.Graphics.MeasureString("B/F....." & CStr(Format(totAmt, "0.00")), txtFont)
                xpos = pgwd - rmg - txtSize.Width - 2
                e.Graphics.DrawString("B/F....." & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)


                'Increment Pagenum 
                pagenum += 1

                'Print Page Num
                txtSize = e.Graphics.MeasureString("[" & pagenum & "]", txtFont)
                xpos = (pgwd - txtSize.Width) / 2
                e.Graphics.DrawString("[" & pagenum & "]", txtFont, Brushes.Black, xpos, ypos + 2)

                xpos = 0
                ypos = 0

                'Insert Next Page
                e.HasMorePages = True
                Exit Sub
            End If
        Loop

        'Print Total Amount at Last Page

        'Draw Line
        e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))
        ypos += 3
        'print Total Amount  at the Lst Page
        txtSize = e.Graphics.MeasureString("Total Amount : " & CStr(Format(totAmt, "0.00")), txtFont)
        xpos = pgwd - rmg - txtSize.Width - 2
        e.Graphics.DrawString("Total Amount : " & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)


        'Print Page Number at Last Page
        'Draw Line
        e.Graphics.DrawLine(Pens.Black, New PointF(lmg, (pght - bmg - 50)), New PointF(pgwd - rmg, (pght - bmg - 50)))

        'Increment Pagenum 
        pagenum += 1

        'Print Page Num
        txtSize = e.Graphics.MeasureString("[" & pagenum & "]", txtFont)
        xpos = (pgwd - txtSize.Width) / 2
        e.Graphics.DrawString("[" & pagenum & "]", txtFont, Brushes.Black, xpos, (pght - bmg - 50) + 2)


        'Stop to Insert Next Page
        e.HasMorePages = False

    End Sub

End Class

Thanks very much Santanu Das
Your code solves my problem.
With further reading I will become perfect this kind of non reportviewer printing
gbhs

@gbhs
Hello, in my previous post I said how could we use an array to print in PrintDocument Object.
Now I am writing here how to generate a simple printable report from a database.
I take here a data table, named "Stock" of 2000 records and making print preview.
PrintDocument PrintPage event fired automaticaly when you assign PrintPreviewDialog's Document property to PrintDicument1
If you try to get print from printer, simply call Print() method of PrintDocument1. But it will print all pages.
Here I use three Events of PrintDoment and try to show how they work.
1. BeginPrint Event (To set the pageSetUp priperty and Open the DataTable)
2. PrintPage Event (To print data in the page)
3. EndPrint Event (To close DataTable at the end of the print)

Imports System
Imports System.Drawing.Printing
Imports System.Text
Imports System.Security.Cryptography
Imports System.Data
Imports System.Data.SqlClient


Public Class Form1

    'Declaring variables
    Dim stkDataPath As String                        ' Store Database path
    Dim stkConnection As New SqlClient.SqlConnection ' SQL Connection String
    Dim stkCommand As New SqlCommand                 ' SQL Quarry Command
    Dim stkReader As SqlDataReader                   ' SQL Data Table Reader


    Dim totAmt As Double                             ' To store Subtotal
    Dim prntRW As Integer                            ' To store Serial No.
    Dim xpos, ypos As Integer                        ' To store Cursor's Horizontal and Vertical Position
    Dim qtypos, rtpos As Integer                     ' To set numerical data' right alingment
    Dim pagenum As Integer                           ' To count page number

    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        ' Event will be fired when Form will try to close.
        'Close Connection and exit
        Me.CloseConnection()

    End Sub

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        'Open SQL Connection at the time of form loading
        Me.OpenConnection()

    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        PDoc.DocumentName = "Stock Statement"

        'Assigning Print Preview Controls Document Property and Show
        PVDlg.Document = PDoc
        PVDlg.ShowDialog()


    End Sub

    'Opennning Database Connection
    Private Sub OpenConnection()

        'Store Database Name with Path into  a variable
        stkDataPath = IIf(Mid(Application.StartupPath(), Len(Application.StartupPath()), 1) <> "\", Application.StartupPath() & "\PrintPreview.mdf", Application.StartupPath() & "PrintPreview.mdf")

        'Checking Connection Status
        If stkConnection.State = ConnectionState.Open Then stkConnection.Close()

        'Assigning Connection String Property
        stkConnection.ConnectionString = "Server=.\SQLExpress;AttachDbFilename=" & stkDataPath & ";Trusted_Connection=Yes; Connect Timeout=30; User Instance=True;"

        'Now Open The Connection
        stkConnection.Open()

    End Sub

    'Closing DataBase Connection
    Private Sub CloseConnection()
        If stkConnection.State = ConnectionState.Open Then stkConnection.Close()
    End Sub




    'PrintDocument BeginPrint event atomatically fired before printPage event.
    Private Sub PDoc_BeginPrint(sender As Object, e As System.Drawing.Printing.PrintEventArgs) Handles PDoc.BeginPrint

        'declaring pagesetting variable
        Dim pgs As New PageSettings

        'Initializing Page Setting values
        pgs.Margins.Top = 25
        pgs.Margins.Bottom = 25
        pgs.Margins.Left = 25
        pgs.Margins.Right = 25

        'Checking Orientation
        If RadioButton1.Checked = True Then
            pgs.Landscape = False
        ElseIf RadioButton2.Checked = True Then
            pgs.Landscape = True
        End If

        'Assigning PrintDocument Default Page Settings
        PDoc.DefaultPageSettings = pgs

        'Initializing Serial No,Total Amount & Page Number
        prntRW = 0
        totAmt = 0.0#
        pagenum = 0


        ' Try to open Data Table
        stkCommand.CommandType = CommandType.Text
        stkCommand.CommandText = "Select * From Stock"
        stkCommand.Connection = stkConnection

        stkReader = stkCommand.ExecuteReader

    End Sub

    Private Sub PDoc_EndPrint(sender As Object, e As System.Drawing.Printing.PrintEventArgs) Handles PDoc.EndPrint
        'Event fired after PrintPage event

        'Close data table
        stkReader.Close()
        stkCommand.Dispose()
    End Sub


    Private Sub PDoc_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles PDoc.PrintPage
        'declaring local varibles
        Dim lmg, rmg, tmg, bmg As Integer 'margines of four sides
        Dim pght, pgwd As Integer         'Page height and width
        Dim Arht, Arwd As Integer         'Printable area height and width

        'Declaring Font and size Variables
        Dim txtFont As Font
        Dim txtSize As SizeF

        'initializing local variables to store Page Margins
        With e.PageSettings
            lmg = .Margins.Left
            rmg = .Margins.Right
            tmg = .Margins.Top
            bmg = .Margins.Bottom

            'Take the page height and width as per orientation
            If .Landscape Then
                pght = .PaperSize.Width
                pgwd = .PaperSize.Height
            Else
                pght = .PaperSize.Height
                pgwd = .PaperSize.Width
            End If
        End With

        'initializing the printable height and width
        Arht = pght - tmg - bmg
        Arwd = pgwd - lmg - rmg

        ' Turn on antialias for text to smooth the edge
        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias



        'Printing Headings*******************************************************************

        'Initializing Y-Position
        ypos = tmg + 10

        'Print Heading in the First page
        If pagenum = 0 Then

            'Initializing Font
            txtFont = New Font("Georgia", 16, FontStyle.Bold Or FontStyle.Underline)

            'Initializing Text size

            txtSize = e.Graphics.MeasureString("Report", txtFont)

            xpos = (Arwd - txtSize.Width) / 2
            ypos = tmg + 10
            e.Graphics.DrawString("Stock Statement", txtFont, Brushes.Black, xpos, ypos)

            ypos += txtSize.Height + 10

            'Printing Report Date and Time
            'Initializing Font
            txtFont = New Font("Verdana", 10, FontStyle.Regular)
            txtSize = e.Graphics.MeasureString("Reporting Date : " & Now.Date, txtFont)

            e.Graphics.DrawString("Reporting Date : " & Now.Date, txtFont, Brushes.Black, pgwd - rmg - txtSize.Width, ypos)

            ypos += txtSize.Height
            e.Graphics.DrawString("Reporting Time : " & Format(IIf(Now.Hour > 12, Now.Hour - 12, Now.Hour), "00") & ":" & Format(Now.Minute, "00") & ":" & Format(Now.Second, "00"), txtFont, Brushes.Black, pgwd - rmg - txtSize.Width, ypos)

            ypos += txtSize.Height

            'Draw line
            e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))

            ypos += 3

        End If


        'draw headings for details on every page

        'Initializing Font
        txtFont = New Font("Times New Roman", 12, FontStyle.Bold)

        e.Graphics.DrawString("Sl. No.", txtFont, Brushes.Black, lmg, ypos)

        txtSize = e.Graphics.MeasureString("Sl. No.", txtFont)
        xpos = lmg + txtSize.Width + 10
        e.Graphics.DrawString("Product Name", txtFont, Brushes.Black, xpos, ypos)


        txtSize = e.Graphics.MeasureString("Total Value", txtFont)
        xpos = pgwd - rmg - txtSize.Width
        e.Graphics.DrawString("Total Value", txtFont, Brushes.Black, xpos, ypos)

        txtSize = e.Graphics.MeasureString("Rate (Single)", txtFont)
        xpos -= txtSize.Width + 30
        e.Graphics.DrawString("Rate (Single)", txtFont, Brushes.Black, xpos, ypos)
        rtpos = xpos + txtSize.Width - 10

        txtSize = e.Graphics.MeasureString("Quantity", txtFont)
        xpos -= txtSize.Width + 20
        e.Graphics.DrawString("Quantity", txtFont, Brushes.Black, xpos, ypos)
        qtypos = xpos + txtSize.Width - 5

        'Draw line
        ypos += txtSize.Height
        e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))
        ypos += 2



        'Printing Details*****************************************************************

        'Initializing Font
        txtFont = New Font("Garamond", 12, FontStyle.Regular)

        'Print subtotal of the previous page at the top of the each page
        If pagenum > 0 Then
            txtSize = e.Graphics.MeasureString("C/F....." & CStr(Format(totAmt, "0.00")), txtFont)
            xpos = pgwd - rmg - txtSize.Width - 2
            e.Graphics.DrawString("C/F....." & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)
            ypos += txtSize.Height
        End If


        'Check DataReader is empty or not
        If stkReader.HasRows Then
            'Loop for readinr every data row
            Do While stkReader.Read

                'Try to print left Align Data
                'Print Serial No.
                txtSize = e.Graphics.MeasureString("Sl. No.", txtFont)
                xpos = lmg + txtSize.Width

                txtSize = e.Graphics.MeasureString(CStr(prntRW + 1) & ".", txtFont)
                xpos -= txtSize.Width
                e.Graphics.DrawString(CStr(prntRW + 1) & ".", txtFont, Brushes.Black, xpos, ypos)


                'Print Product Name
                xpos += txtSize.Width + 12
                e.Graphics.DrawString(stkReader.Item("Product_Name"), txtFont, Brushes.Black, xpos, ypos)





                'Try to print Numerical Data
                'We have to moov the Cursor From Rightto Left
                'Neumerical Data are always align by Right 
                'Storing Cursor's Horizontal Position at the end of the printable area
                xpos = pgwd - rmg

                'Print Total value of individual product
                txtSize = e.Graphics.MeasureString(Format(stkReader.Item("Product_Value"), "0.00"), txtFont)
                'move Cursor's Horizontal Position to left by the width of the Printable Text from Right edge.
                xpos -= txtSize.Width + 2
                e.Graphics.DrawString(Format(stkReader.Item("Product_Value"), "0.00"), txtFont, Brushes.Black, xpos, ypos)


                'print Rate per single Item
                txtSize = e.Graphics.MeasureString(Format(stkReader.Item("Product_Rate"), "0.00"), txtFont)
                'move Cursor's Horizontal Position to left by the width of the Printable Text
                xpos = rtpos - txtSize.Width
                e.Graphics.DrawString(Format(stkReader.Item("Product_Rate"), "0.00"), txtFont, Brushes.Black, xpos, ypos)

                'print Quantity
                txtSize = e.Graphics.MeasureString(stkReader.Item("Product_Qty") & " Pcs.", txtFont)
                'move Cursor's Horizontal Position to left by the width of the Printable Text
                xpos = qtypos - txtSize.Width
                e.Graphics.DrawString(stkReader.Item("Product_Qty") & " Pcs.", txtFont, Brushes.Black, xpos, ypos)


                'Adding total values 
                totAmt += stkReader.Item("Product_Value")

                'Increment prin row by 1
                prntRW += 1

                'Change the vertical Position
                ypos += txtSize.Height

                'Checking Cursor's vertical position near to the bottom edge
                'If this is >= botoom edge then draw a line , print the page sub total and page number
                'then go to the next page to print.
                If (ypos >= (pght - bmg) - 50) Then

                    'Draw Line
                    e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))


                    'print sub total of current page at bottom position
                    txtSize = e.Graphics.MeasureString("B/F....." & CStr(Format(totAmt, "0.00")), txtFont)
                    xpos = pgwd - rmg - txtSize.Width - 2
                    e.Graphics.DrawString("B/F....." & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)


                    'Increment Pagenum 
                    pagenum += 1

                    'Print Page Num
                    txtSize = e.Graphics.MeasureString("[" & pagenum & "]", txtFont)
                    xpos = (pgwd - txtSize.Width) / 2
                    e.Graphics.DrawString("[" & pagenum & "]", txtFont, Brushes.Black, xpos, ypos + 2)

                    xpos = 0
                    ypos = 0

                    'Insert Next Page
                    e.HasMorePages = True
                    Exit Sub

                End If
            Loop

            'Print Total Amount at Last Page

            'Draw Line
            e.Graphics.DrawLine(Pens.Black, New PointF(lmg, ypos), New PointF(pgwd - rmg, ypos))
            ypos += 3
            'print Total Amount  at the Lst Page
            txtSize = e.Graphics.MeasureString("Total Amount : " & CStr(Format(totAmt, "0.00")), txtFont)
            xpos = pgwd - rmg - txtSize.Width - 2
            e.Graphics.DrawString("Total Amount : " & CStr(Format(totAmt, "0.00")), txtFont, Brushes.Black, xpos, ypos)


            'Print Page Number at Last Page
            'Increment Pagenum 
            pagenum += 1

            'Print Page Num
            txtSize = e.Graphics.MeasureString("[" & pagenum & "]", txtFont)
            xpos = (pgwd - txtSize.Width) / 2
            e.Graphics.DrawString("[" & pagenum & "]", txtFont, Brushes.Black, xpos, (pght - bmg - 50))

        Else

            e.Graphics.DrawLine(Pens.Black, New PointF(lmg, (pght - bmg - 50)), New PointF(pgwd - rmg, (pght - bmg - 50)))

            'Increment Pagenum 
            pagenum += 1

            'Print Page Num
            txtSize = e.Graphics.MeasureString("[" & pagenum & "]", txtFont)
            xpos = (pgwd - txtSize.Width) / 2
            e.Graphics.DrawString("[" & pagenum & "]", txtFont, Brushes.Black, xpos, (pght - bmg - 50) + 2)

        End If


        'Stop to Insert Next Page
        e.HasMorePages = False


    End Sub

End Class
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.