Click here to Skip to main content
15,886,776 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to print database value on multiple pages (30 values on one page). By using while(dr.Read()) loops goes infinitely and the same data is displaying on each page, How to solve it?

What I have tried:

private void test2_Load(object sender, EventArgs e)
        {

           itemperpage = 0;
            printPreviewDialog1.Document = printDocument1;

            ((ToolStripButton)((ToolStrip)printPreviewDialog1.Controls[1]).Items[0]).Enabled
            = false;//disable the direct print from printpreview.as when we click that Print button PrintPage event fires again.


            printDocument1.DefaultPageSettings.PaperSize = paperSize;
            printPreviewDialog1.ShowDialog();
        }


private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            int kx = 25;
            int ky = 50;
            con.Close();
            con.Open();
            String sql = "SELECT * from cash_bill";
            cmd = new OleDbCommand(sql, con);
            dr1 = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            
               while (dr1.Read()) 
                {
                    e.Graphics.DrawString(dr1[7].ToString(), printFont, Brushes.Black, kx + 75, ky + 5);
                   
           
                    if (itemperpage < 29) 
                    {
                        itemperpage += 1; 
                        e.HasMorePages = false; 
                        ky = ky + 50;
                    }

                    else 
                    {
                        itemperpage = 0; 
                        e.HasMorePages = true; 
                         return;

                    }
                   
                }
                con.Close();
            }
Posted
Updated 26-Nov-19 20:34pm

1 solution

Well ... you read the same data from the DB each time that method is executed - so as long as the DB contains 30 or more items, you will print the first page, tell the system there are more pages to print, and exit. The system will then call you again to print the next page, you will read the same data from the DB, and the cycle goes round again.

Your method needs to be aware of which page it is printing, and either:
1) "Skip" data from previous pages by ignoring lines you have printed already,
Or
2) (Better) only fetching the data for one page at a time.

You can do this in many ways, but if your DB table has an integer ID value (an IDENTITY perhaps), then you can store the last printed ID and then change your query to
SQL
SELECT TOP 30 * FROM cash_bill WHERE ID > @LastID ORDER BY ID ASC
And supplying the last ID value you printed as the parameter. By setting the last ID value to int.MinValue before you print the last page the first page will automatically be printed.

Additionally, you need to Close and Dispose your Connection, Command, and Reader objects properly - dump the CommandBehavior.CloseConnection stuff and create your items inside a using block:
C#
using (SqlConnection con = new SqlConnection(strConnect))
    {
    con.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT Age, Description FROM myTable WHERE ID = @ID", con))
        {
        cmd.Parameters.AddWithValue("@ID", myTextBox.Text);
        using (SqlDataReader reader = cmd.ExecuteReader())
            {
            while (reader.Read())
                {
                int age = (int) reader["Age"];
                string desc = (string) reader["Description"];
                Console.WriteLine($"{age}\n{desc}");
                }
            }
        }
    }
Then the system will Close and Dispose for you immediately they go out of scope.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900