"Page X of Y" Footer

Hello,

I'm trying to create a page footer using the built in Grid PDF export in a format "Page X of Y" with X being the current page and Y being the total pages.

I've looked over the documentation and can find no mention of this type of page footer.  Is it possible to do this? If so, please direct me to the section of the documentation that show how to do th


5 Replies

PS Prathap Senthil Syncfusion Team May 3, 2024 02:16 AM UTC

Hi Justin,

Based on your requirements, we have achieved the following possible ways to meet them. Kindly refer to the code snippet and sample below for your reference.

public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)

{

     if (args.Item.Id == "Grid_pdfexport"//Id is combination of Grid's ID and itemname

     {

         PdfDocument document = new PdfDocument();

         int rowsPerPage = 50; // Number of rows per page

         int totalPages = (Orders.Count / rowsPerPage) + (Orders.Count % rowsPerPage == 0 ? 0 : 1); // Adjust total pages calculation

 

         for (int currentPage = 1; currentPage <= totalPages; currentPage++)

         {

             PdfSection section = document.Sections.Add();

             PdfPage page = section.Pages.Add();

             PdfBrush brush = new PdfSolidBrush(Color.Black);

 

             PdfGrid grid = new PdfGrid();

             grid.Columns.Add(Grid.Columns.Count);

             PdfGridRow[] headerRow = grid.Headers.Add(1);

 

             var GridColHeader = Grid.Columns.Select(x => x.HeaderText).ToList();

             for (var i = 0; i < Grid.Columns.Count; i++)

             {

                 headerRow[0].Cells[i].Value = GridColHeader[i];

             }

 

             // Calculate index range for the current page

             int startIndex = (currentPage - 1) * rowsPerPage;

             int endIndex = Math.Min(currentPage * rowsPerPage, Orders.Count);

 

             // Add Rows to the grid based on the current page

             for (int i = startIndex; i < endIndex; i++)

             {

                 PdfGridRow row = grid.Rows.Add();

                 //assign cells based on grid's columns

                 row.Cells[0].Value = Orders[i].OrderID.ToString();

                 row.Cells[1].Value = Orders[i].CustomerID;

                 row.Cells[2].Value = Orders[i].OrderDate.ToString();

                 row.Cells[3].Value = Orders[i].Freight.ToString();

             }

 

             //draw the grid below the pdf Footer

             PdfGridLayoutResult result = grid.Draw(page, new PointF(0, 0));

 

             // Add footer to the current page

             AddFooter(page, currentPage, totalPages);

         }

 

         MemoryStream stream = new MemoryStream();

         document.Save(stream);

         //Close the document

         document.Close(true);

         await Runtime.InvokeVoidAsync("exportSave", new object[] { "output.pdf", Convert.ToBase64String(stream.ToArray()) });

 

     }

}

 

 

public static void AddFooter(PdfPage page, int currentPage, int totalPages)

{

     PdfFont font = new PdfStandardFont(PdfFontFamily.Helvetica, 7);

     PdfBrush brush = new PdfSolidBrush(Color.Black);

 

     // Calculate the position to draw the footer text

     float x = page.Graphics.ClientSize.Width - font.MeasureString($"Page {currentPage} of {totalPages}").Width - 10; // 10 is for margin

     float y = page.Graphics.ClientSize.Height - font.Height - 10; // 10 is for margin

 

     // Draw the footer text on the page

     page.Graphics.DrawString($"Page {currentPage} of {totalPages}", font, brush, new PointF(x, y));

}

 


Regards,
Prathap Senthil


Attachment: BlazorApp1201_637bef3d.zip


JT Justin Turner May 6, 2024 01:24 PM UTC

Thanks for the response.


However, this code example is based on a significant assumption that there is a fixed number of rows per page.  Many of the cells in the pdf I need this Page X of Y footer on are string based data of varying lengths.  This causes the rows to heighten and shorten depending on the text data in the cell.  There is no way to guarantee there will be the same number of rows per page for the entirety of the PDF.


Is there a way to generate the the "Page X of Y" footer when each page could have a varying number of rows?



PS Prathap Senthil Syncfusion Team May 7, 2024 01:23 PM UTC

Before proceeding with the reporting of the concern, we require some additional clarification from your end. Please share the following details to proceed further:

  • Can you provide a screenshot demonstrating any difficulties faced when attempting to ensure a consistent Page X of Y footer while dealing with fluctuating row heights caused by text data of varying lengths?
  • Do you anticipate the need for rendering a different number of rows on each page of a PDF? How would you address this expectation?
  • If possible, kindly share your attempt to replicate the issue using the previous attached sample.

The details requested above will be very helpful in validating the reported query on our end and providing a solution as soon as possible. Thanks for your understanding.



JT Justin Turner May 7, 2024 05:44 PM UTC

"Can you provide a screenshot demonstrating any difficulties faced when attempting to ensure a consistent Page X of Y footer while dealing with fluctuating row heights caused by text data of varying lengths?"


I've attached 2 images of the same PDF data, but modifying 1 data point to be much longer.  Comparing these 2 examples you can clearly see how variable length string data can affect the number of rows on the page.


"Do you anticipate the need for rendering a different number of rows on each page of a PDF? How would you address this expectation?"

I 100% know that there will be variable length string data in the grid results. As far as rendering the PDF, it does not matter that the number of rows will be different per page.

"
If possible, kindly share your attempt to replicate the issue using the previous attached sample."

At this point in time I have been tasked to other work and cannot implement the code example listed before.  Also, I know that it will not work to solve the issue; see answer to question 1.


Attachment: Variable_String_Length_Examples_d09b9fdb.zip


PS Prathap Senthil Syncfusion Team May 8, 2024 12:33 PM UTC

Based on your requirements, we have modified the sample. Please refer to the attached code snippet and sample for your reference.

  public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)

  {

      if (args.Item.Id == "Grid_pdfexport"//Id is combination of Grid's ID and itemname

      {

          PdfDocument document = new PdfDocument();

          Footer(document, new RectangleF(0, 0, 595, 50));

 

          int rowsPerPage = 50; // Number of rows per page

          int totalPages = (Orders.Count / rowsPerPage) + (Orders.Count % rowsPerPage == 0 ? 0 : 1); // Adjust total pages calculation

 

          for (int currentPage = 1; currentPage <= totalPages; currentPage++)

          {

              PdfSection section = document.Sections.Add();

              if (currentPage == 1)

                  section.PageSettings.Size = new SizeF(595, 842); // A4 size

              else

              {

                  section.PageSettings.Size = new SizeF(842f, 1190f);

              }

              PdfPage page = section.Pages.Add();

              RectangleF bounds = new RectangleF(0, 0, document.Pages[0].GetClientSize().Width, 50);

              PdfPageTemplateElement header = new PdfPageTemplateElement(bounds);

 

              document.Template.Top = header;

              PdfBrush brush = new PdfSolidBrush(Color.Black);

 

              PdfGrid grid = new PdfGrid();

              grid.Columns.Add(Grid.Columns.Count);

              PdfGridRow[] headerRow = grid.Headers.Add(1);

 

              var GridColHeader = Grid.Columns.Select(x => x.HeaderText).ToList();

              for (var i = 0; i < Grid.Columns.Count; i++)

              {

                  headerRow[0].Cells[i].Value = GridColHeader[i];

              }

 

              // Calculate index range for the current page

              int startIndex = (currentPage - 1) * rowsPerPage;

              int endIndex = Math.Min(currentPage * rowsPerPage, Orders.Count);

 

              // Add Rows to the grid based on the current page

              for (int i = startIndex; i < endIndex; i++)

              {

                  PdfGridRow row = grid.Rows.Add();

                  //assign cells based on grid's columns

                  row.Cells[0].Value = Orders[i].OrderID.ToString();

                  row.Cells[1].Value = Orders[i].CustomerID;

                  row.Cells[2].Value = Orders[i].OrderDate.ToString();

                  row.Cells[3].Value = Orders[i].Freight.ToString();

              }

 

              //draw the grid below the pdf Footer

              PdfGridLayoutResult result = grid.Draw(page, new PointF(0, 0));

 

          }

 

          MemoryStream stream = new MemoryStream();

          document.Save(stream);

          //Close the document

          document.Close(true);

          await Runtime.InvokeVoidAsync("exportSave", new object[] { "output.pdf", Convert.ToBase64String(stream.ToArray()) });

 

      }

  }

  public static void Footer(PdfDocument pdfDocument, RectangleF bounds)

  {

      PdfPageTemplateElement footer = new PdfPageTemplateElement(bounds);

      PdfFont font = new PdfStandardFont(PdfFontFamily.Helvetica, 7);

      PdfBrush brush = new PdfSolidBrush(Color.Black);

      //Create page number field.

      PdfPageNumberField pageNumber = new PdfPageNumberField(font, brush);

      //Create page count field.

      PdfPageCountField count = new PdfPageCountField(font, brush);

      //Add the fields in composite fields.

      PdfCompositeField compositeField = new PdfCompositeField(font, brush, "Page {0} of {1}", pageNumber, count);

      compositeField.Bounds = footer.Bounds;

      //Draw the composite field in footer.

      compositeField.Draw(footer.Graphics, new PointF(470, 30));

      //Add the footer template at the bottom.

      pdfDocument.Template.Bottom = footer;

  }

 




Attachment: BlazorApp1201_8bc2eaba.zip

Loader.
Up arrow icon