Click here to Skip to main content
15,886,724 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
Hi All,

I am trying to create a PDF file that pulls all the data from a database and populates the rows over the pages. I'm using PDFSharp to create the PDF. As most of you probably know, PDFSharp does not create page breaks automatically so I have to figure out a way to create the page breaks myself at certain points.

My Problem: The data is being extracted and printed beautifully, but the first page has 28 rows of data where it should only have 10, the second page has 11 rows and the third page has the rest. The other problem is that the rows of data is being printed at the correct y position on the first and the second page, but on the third page, the rows are being printed in the middle of the page. I am thinking that the problem has something to do with my loops, I might have confused myself when writing this code, as its been driving me insane for little over a week now.

Can ANYONE please help me correct my loops?

Here is my code:
C#
public void PrintPDFDisplayingLogInformation(DataGridView dataPayments)
        {
            DataSet ds = new DataSet();
            int i = 0;
            int yPoint = 0;
            int yNextPagePoint = 0;
            string surname = null;
            string name = null;
            string lastPaymentDate = null;
            string membership = null;
            string gymId = null;
            string lastPaidAmount = null;
            string arrears = null;
            string month = DateTime.Now.ToString("MM");
            string year = DateTime.Now.Year.ToString();

            ds = paymentService.RetrieveFullPaymentLogForPDF();

            PdfDocument pdf = new PdfDocument();
            pdf.Info.Title = "Payments This Month";
            PdfPage pdfPage = pdf.AddPage();
            XGraphics graph = XGraphics.FromPdfPage(pdfPage);
            XFont heading = new XFont("Times New Roman", 20, XFontStyle.Bold);
            XFont subHeading = new XFont("Times New Roman", 12, XFontStyle.Bold);
            XFont fontBold = new XFont("Times New Roman", 8, XFontStyle.Bold);
            XFont font = new XFont("Times New Roman", 8, XFontStyle.Regular);
            XFont smallFont = new XFont("Times New Roman", 6, XFontStyle.Bold);

            //Draw Header Of Document.
            graph.DrawString("Full Payment Log " + DateTime.Now.ToString("yyyy/MM/dd"), heading, XBrushes.Black,
                             new XRect(60, 60, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);

            //Draw Sub-Heading For Personal Details.
            graph.DrawString("Last Payment", subHeading, XBrushes.Black,
                             new XRect(60, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Surname", subHeading, XBrushes.Black,
                             new XRect(170, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Name", subHeading, XBrushes.Black,
                             new XRect(250, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Type", subHeading, XBrushes.Black,
                             new XRect(315, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Gym ID", subHeading, XBrushes.Black,
                             new XRect(370, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Paid", subHeading, XBrushes.Black,
                             new XRect(435, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);
            graph.DrawString("Arrears", subHeading, XBrushes.Black,
                             new XRect(480, 100, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.TopLeft);

            //Draw Each Row From Database.
            yPoint = yPoint + 120;

            for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
            {
                if ((i % 10) == 0 && i != 0)
                {
                    PdfPage nextPage = pdf.AddPage();
                    XGraphics nextGraph = XGraphics.FromPdfPage(nextPage);
                    yNextPagePoint = yNextPagePoint + 60;
                    for (int count = 0; count <= 10; count++) 
                    {                        
                        surname = ds.Tables[0].Rows[i + count].ItemArray[0].ToString();
                        name = ds.Tables[0].Rows[i + count].ItemArray[1].ToString();
                        membership = ds.Tables[0].Rows[i + count].ItemArray[2].ToString();
                        lastPaidAmount = ds.Tables[0].Rows[i + count].ItemArray[3].ToString();
                        arrears = ds.Tables[0].Rows[i + count].ItemArray[4].ToString();
                        gymId = ds.Tables[0].Rows[i + count].ItemArray[5].ToString();
                        lastPaymentDate = ds.Tables[0].Rows[i + count].ItemArray[6].ToString();

                        //Check Whether Date Is Current Month.
                        if (lastPaymentDate.Contains(year + "/" + month))
                        {
                            nextGraph.DrawString(lastPaymentDate, font, XBrushes.Black, new XRect(60, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }
                        else
                        {
                            nextGraph.DrawString(lastPaymentDate, font, XBrushes.Red, new XRect(60, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }
                        nextGraph.DrawString(surname, font, XBrushes.Black, new XRect(170, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        nextGraph.DrawString(name, font, XBrushes.Black, new XRect(250, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        nextGraph.DrawString(membership, font, XBrushes.Black, new XRect(315, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        nextGraph.DrawString(gymId, font, XBrushes.Black, new XRect(370, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);

                        //Check Whether Member Has Paid For Current Month.
                        if (Convert.ToInt32(lastPaidAmount) != 0)
                        {
                            nextGraph.DrawString(lastPaidAmount, font, XBrushes.Green, new XRect(435, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }
                        else
                        {
                            nextGraph.DrawString(lastPaidAmount, font, XBrushes.Black, new XRect(435, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }

                        //Check Whether Member Is In Arrears.
                        if (Convert.ToInt32(arrears) != 0)
                        {
                            nextGraph.DrawString(arrears, font, XBrushes.Red, new XRect(480, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }
                        else
                        {
                            nextGraph.DrawString(arrears, font, XBrushes.Black, new XRect(480, yNextPagePoint, nextPage.Width.Point, nextPage.Height.Point), XStringFormats.TopLeft);
                        }

                        yNextPagePoint = yNextPagePoint + 15;
                    }
                    //Draw Page Footer.
                    nextGraph.DrawString("PDF Generated With EzyGym Manager",
                                     smallFont, XBrushes.Black, new XRect(300, 800, nextPage.Width.Centimeter, nextPage.Height.Centimeter), XStringFormats.Center);
                    nextGraph.DrawString("Copyright © Minc Development (Pty) Ltd || All Right Reserved",
                                     smallFont, XBrushes.Black, new XRect(300, 807, nextPage.Width.Centimeter, nextPage.Height.Centimeter), XStringFormats.Center);
                    nextGraph.DrawString("Website: http://www.mincdevelopment.co.za",
                                     smallFont, XBrushes.Black, new XRect(300, 814, nextPage.Width.Centimeter, nextPage.Height.Centimeter), XStringFormats.Center);
                    nextGraph.DrawString("Email: info@mincdevelopment.co.za",
                                     smallFont, XBrushes.Black, new XRect(300, 821, nextPage.Width.Centimeter, nextPage.Height.Centimeter), XStringFormats.Center);

                    i = i + 10;
                        
                }
                else
                {
                    surname = ds.Tables[0].Rows[i].ItemArray[0].ToString();
                    name = ds.Tables[0].Rows[i].ItemArray[1].ToString();
                    membership = ds.Tables[0].Rows[i].ItemArray[2].ToString();
                    lastPaidAmount = ds.Tables[0].Rows[i].ItemArray[3].ToString();
                    arrears = ds.Tables[0].Rows[i].ItemArray[4].ToString();
                    gymId = ds.Tables[0].Rows[i].ItemArray[5].ToString();
                    lastPaymentDate = ds.Tables[0].Rows[i].ItemArray[6].ToString();

                    //Check Whether Date Is Current Month.
                    if (lastPaymentDate.Contains(year + "/" + month))
                    {
                        graph.DrawString(lastPaymentDate, font, XBrushes.Black, new XRect(60, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }
                    else
                    {
                        graph.DrawString(lastPaymentDate, font, XBrushes.Red, new XRect(60, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }
                    graph.DrawString(surname, font, XBrushes.Black, new XRect(170, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    graph.DrawString(name, font, XBrushes.Black, new XRect(250, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    graph.DrawString(membership, font, XBrushes.Black, new XRect(315, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    graph.DrawString(gymId, font, XBrushes.Black, new XRect(370, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);

                    //Check Whether Member Has Paid For Current Month.
                    if (Convert.ToInt32(lastPaidAmount) != 0)
                    {
                        graph.DrawString(lastPaidAmount, font, XBrushes.Green, new XRect(435, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }
                    else
                    {
                        graph.DrawString(lastPaidAmount, font, XBrushes.Black, new XRect(435, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }

                    //Check Whether Member Is In Arrears.
                    if (Convert.ToInt32(arrears) != 0)
                    {
                        graph.DrawString(arrears, font, XBrushes.Red, new XRect(480, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }
                    else
                    {
                        graph.DrawString(arrears, font, XBrushes.Black, new XRect(480, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft);
                    }

                    yPoint = yPoint + 15;
                }
            }

                //Draw Page Footer.
                graph.DrawString("PDF Generated With EzyGym Manager",
                                 smallFont, XBrushes.Black, new XRect(300, 800, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.Center);
                graph.DrawString("Copyright © Minc Development (Pty) Ltd || All Right Reserved",
                                 smallFont, XBrushes.Black, new XRect(300, 807, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.Center);
                graph.DrawString("Website: http://www.mincdevelopment.co.za",
                                 smallFont, XBrushes.Black, new XRect(300, 814, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.Center);
                graph.DrawString("Email: info@mincdevelopment.co.za",
                                 smallFont, XBrushes.Black, new XRect(300, 821, pdfPage.Width.Centimeter, pdfPage.Height.Centimeter), XStringFormats.Center);

                string pdfFilename = "Payment_Log_" + DateTime.Now.ToString("yyyy-MM-dd") + ".pdf";
                string strPath = Environment.GetFolderPath(
                             System.Environment.SpecialFolder.DesktopDirectory) + "\\" + pdfFilename;
                pdf.Save(strPath);
                Process.Start(strPath);                
        }


Thank you very much !!
Chris
Posted
Comments
gggustafson 19-Aug-14 17:28pm    
What's graph and nextGraph? Graphics objects? What is PdfDocument? What is paymentService? What is PdfPage? What is XGraphics? What is XFont? And so on. To help you I need to know the using statement. Are you using any third party libraries?

1 solution


Couple of things:



  • Never, ever, change the value of a for loop variable within the body of the for loop. Use a while loop if that is absolutely necessary (in your case it is not).
  • Eliminate count - it's just confusing you.
  • When you have retrieved the data set, declare a table (see below).
  • Loop through the rows once; don't play with indices; keep it simple.
  • Write helper methods to emit the heading, the data line, and the footer.
  • Test against the for loop variable to determine if a footer needs to be emitted.
  • When you emit the footer, shouldn't you also emit the header?
  • At the end of the for loop, emit the footer.


The following is a proposed template.


C#
header ( ... )
    {

    }

draw_line ( ... )
    {

    }
    
footer ( ... )
    {

    }
:
:
DataTable table = ds.Tables [ 0 ];
:
:
header ( ... );

for ( int i = 0; ( i < table.Rows.Count ); i++ )
    {
    DataRow row = table.Rows [ i ];

    surname = row.ItemArray [ 0 ].ToString ( );
    name = row.ItemArray [ 1 ].ToString ( );
    membership = row.ItemArray [ 2 ].ToString ( );
    lastPaidAmount = row.ItemArray [ 3 ].ToString ( );
    arrears = row.ItemArray [ 4 ].ToString ( );
    gymId = row.ItemArray [ 5 ].ToString ( );
    lastPaymentDate = row.ItemArray [ 6 ].ToString ( );

    draw_line ( ... );

    if ( i == 9 )
        {
        footer ( ... );
        // header ( ... ); <- I expected a header on second page
        }
    }
footer ( ... );


The elipses ("...") indicate arguments to be supplied.



Hope that helps.

 
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