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
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
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?
Before proceeding with the reporting of the concern, we require some additional clarification from your end. Please share the following details to proceed further:
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.
"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.
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; }
|