I work on itextcharp library to export grid view to pdf . I face issue header column display within data and it must
display above of data so my issue data rows display above header exactly .
I need to display header on top then details rows data consistence with header
I need header data display on every page header meaning column headers and
title of pdf and and logo with white boxes display on every page so how to solve this issue .
ON end page event of
class pageeventhelper
I add header data because i need display header on every page
What I try as below :
[WebMethod]
public byte[] ExportGridViewToPdf(string[][] gridData, string[] columnNames)
Document document = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
var ms = new MemoryStream();
var writer = PdfWriter.GetInstance(document, ms);
var tahomaFontFile = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Fonts),
"Tahoma.ttf");
var tahomaBaseFont = BaseFont.CreateFont(tahomaFontFile,
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
var tahomaFont = new Font(tahomaBaseFont, 8, Font.NORMAL);
PageEventHelper pageEventHelper = new PageEventHelper(columnNames, tahomaFont, gridData);
writer.PageEvent = pageEventHelper;
document.Open();
for (int i = 0; i < columnNames.Length; i++)
cells[i] = new PdfPCell(new Phrase(row[i], tahomaFont));
cells[i].FixedHeight = 25f;
table.AddCell(cells[i]); // Add each cell individually
Paragraph paragraph = new Paragraph();
Chunk dateChunk = new Chunk("Print Date :" + DateTime.Now.ToString("dd-MM-yyyy"));
paragraph.Add(dateChunk);
paragraph.Add(new Chunk(" ")); // Adjust the spacing as needed
Chunk ministryChunk = new Chunk("Ministry of Industry AND Trade");
paragraph.Add(ministryChunk);
paragraph.Alignment = Element.ALIGN_LEFT;
PdfPCell dateCell = new PdfPCell(paragraph)
Colspan = columnNames.Length, // Span across all columns
BackgroundColor = new BaseColor(System.Drawing.Color.LightGray),
HorizontalAlignment = Element.ALIGN_RIGHT,
FixedHeight = 30f // Set the desired height (adjust as needed)
table.AddCell(dateCell);
document.Add(table);
document.Close();
writer.Close();
HttpContext.Current.Response.ContentType = "application/pdf";
return ms.ToArray();
catch (Exception ex)
throw new Exception("Error exporting GridView to PDF: " + ex.Message);
using iText.Kernel.Pdf;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
namespace EREG.BusinessLayer
public class PageEventHelper : PdfPageEventHelper
private int pageNumber = 0;
private int totalPages = 0;
PdfTemplate footerTemplate;
BaseFont bf = null;
PdfContentByte cb;
private readonly string[] _columnNames;
private readonly iTextSharp.text.Font _tahomaFont;
private readonly string[][] _gridData;
public PageEventHelper(string[] columnNames, iTextSharp.text.Font tahomaFont, string[][] gridData)
_columnNames = columnNames;
_tahomaFont = tahomaFont;
_gridData = gridData;
public override void OnOpenDocument(iTextSharp.text.pdf.PdfWriter writer, Document document)
bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb = writer.DirectContent;
footerTemplate = cb.CreateTemplate(50, 50);
catch (DocumentException de)
//handle exception here
catch (System.IO.IOException ioe)
//handle exception here
public override void OnStartPage(iTextSharp.text.pdf.PdfWriter writer, Document document)
base.OnStartPage(writer, document);
pageNumber++;
public override void OnCloseDocument(iTextSharp.text.pdf.PdfWriter writer, Document document)
base.OnCloseDocument(writer, document);
//totalPages = writer.PageNumber;
footerTemplate.BeginText();
footerTemplate.SetFontAndSize(bf, 12);
footerTemplate.SetTextMatrix(0, 0);
footerTemplate.ShowText((writer.PageNumber - 1).ToString());
footerTemplate.EndText();
public override void OnEndPage(iTextSharp.text.pdf.PdfWriter writer, Document document)
base.OnEndPage(writer, document);
// Create a new PdfContentByte instance
PdfContentByte cb = writer.DirectContent;
// Add page number at the bottom
string pageNumberText = $"Page {writer.PageNumber} of ";
float pageNumberWidth = bf.GetWidthPoint(pageNumberText, 12);
float pageNumberX = (document.PageSize.Width - pageNumberWidth) / 2;
float pageNumberY = document.BottomMargin;
cb.BeginText();
cb.SetFontAndSize(bf, 12);
cb.SetTextMatrix(pageNumberX, pageNumberY);
cb.ShowText(pageNumberText);
cb.EndText();
// Add the total pages placeholder
cb.AddTemplate(footerTemplate, pageNumberX + pageNumberWidth, pageNumberY);
// Create and add the header table
PdfPTable headerTable = new PdfPTable(_columnNames.Length) { RunDirection = iTextSharp.text.pdf.PdfWriter.RUN_DIRECTION_RTL };
string imagePath = System.IO.Path.Combine(AppContext.BaseDirectory, "assets", "images", "logo_kw.png");
System.Drawing.Image logoImage = System.Drawing.Image.FromFile(imagePath);
iTextSharp.text.Image itextImage = iTextSharp.text.Image.GetInstance(logoImage, BaseColor.LIGHT_GRAY);
string imagePath2 = System.IO.Path.Combine(AppContext.BaseDirectory, "assets", "images", "favicon.png");
System.Drawing.Image logoImage2 = System.Drawing.Image.FromFile(imagePath2);
iTextSharp.text.Image itextImage2 = iTextSharp.text.Image.GetInstance(logoImage2, BaseColor.LIGHT_GRAY);
//string imagePath3 = System.IO.Path.Combine(AppContext.BaseDirectory, "assets", "images", "logo-newkuwit.png");
//System.Drawing.Image logoImage3 = System.Drawing.Image.FromFile(imagePath3);
//iTextSharp.text.Image itextImage3 = iTextSharp.text.Image.GetInstance(logoImage3, BaseColor.LIGHT_GRAY);
PdfPCell logoCell = new PdfPCell();
logoCell.Colspan = _columnNames.Length; // Span across all columns
logoCell.BackgroundColor = new BaseColor(System.Drawing.Color.SkyBlue);
logoCell.HorizontalAlignment = Element.ALIGN_CENTER;
logoCell.VerticalAlignment = Element.ALIGN_MIDDLE;
logoCell.FixedHeight = 100f;
PdfPTable imageTable = new PdfPTable(2);
imageTable.WidthPercentage = 100;
imageTable.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
itextImage.ScaleToFit(logoCell.FixedHeight - 10, logoCell.FixedHeight - 30);
imageTable.AddCell(new PdfPCell(itextImage) { Colspan = 1, Border = iTextSharp.text.Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_CENTER, VerticalAlignment = Element.ALIGN_MIDDLE });
itextImage2.ScaleToFit(logoCell.FixedHeight - 10, logoCell.FixedHeight - 30);
imageTable.AddCell(new PdfPCell(itextImage2) { Colspan = 1, Border = iTextSharp.text.Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_RIGHT, VerticalAlignment = Element.ALIGN_MIDDLE });
//itextImage3.ScaleToFit(logoCell.FixedHeight - 10, logoCell.FixedHeight - 30);
//imageTable.AddCell(new PdfPCell(itextImage3) { Colspan = 1, Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_LEFT, VerticalAlignment = Element.ALIGN_MIDDLE });
logoCell.AddElement(imageTable);
headerTable.AddCell(logoCell);
headerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
headerTable.LockedWidth = true;
string titleText = "احصائية تسجيل المستفيد الفعلي طبقاً للجهة الرقابية";
var titleCell = new PdfPCell(new Phrase(titleText, _tahomaFont))
Colspan = _columnNames.Length, // Span across all columns
BackgroundColor = new BaseColor(System.Drawing.Color.LightGray),
HorizontalAlignment = Element.ALIGN_CENTER,
FixedHeight = 30f // Set the desired height (adjust as needed)
headerTable.AddCell(titleCell);
foreach (var columnName in _columnNames)
var cell = new PdfPCell(new Phrase(columnName, _tahomaFont));
cell.BackgroundColor = new BaseColor(System.Drawing.Color.LightGray);
cell.HorizontalAlignment = Element.ALIGN_CENTER;
headerTable.AddCell(cell);
headerTable.WriteSelectedRows(0, -1, document.LeftMargin, document.PageSize.Height - document.TopMargin - 20, cb);
Hi @Ahmed Salah,
Could you provide your front-end code so we can reproduce your issue and help you troubleshoot it better?
I tried running your code, but the part (creating and adding the header table) did not run successfully. Can you provide the correct code? I noticed that you used iText.Kernel.Pdf in the references; have you actually used it?
contentType: "application/json; charset=utf-8",
url: "../BusinessLayer/WebMethods.asmx/ExportGridViewToPdf",
data: JSON.stringify({ gridData: tableData, columnNames: columns }),
responseType: 'arraybuffer',
success: function (response) {
var bytes = new Uint8Array(response.d);
var blob = new Blob([bytes], { type: "application/pdf" });
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.setAttribute("download", "GridView.pdf");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
error: function (xhr, status, error) {
// Handle the error response
console.error("Error exporting PDF: " + error);
I would suggest that you adopt some kind of reporting system.
The problem is you attempting to use a GridView, and not only convert the GridView to a PDF (which as you can see can be quite a bit of work).
However, "more" of a challenge is now you want the GridView heading to appear at the top of each page. And probably later on, someone will ask that you include a page number. Then maybe later on, someone wants a grouping in the report. Then maybe later on, you need a report with totals.
In other words, the result is you going to be writing boatloads of code, and all that code will be difficult to maintain, difficult to change, difficult to add new simple features like a heading at the top of each page, page numbers etc. And then when all that work is done, you THEN want the results as a PDF.
Hence, I suggest you don't hand code the output, don't try to make the PDF, and also don't try to convert and change the GridView into some kind of "reporting" system.
There are great tools for this purpose. In fact, webforms and even vs2022 still supports using what is called RDL reports (RDL = Report definition Language). So, I suggest you ensure that the RDL reporting tools are installed, and then consider using a report.
So, for a simple report of hotels, then with the report writer, I lay it out like this:
Now, when I run the page, the result is this:
Note VERY close how the report system can export to Excel, Word or as a PDF. And note how there is even a print the PDF button in above. And when I choose PDF, it downloads the PDF for me (again saving a lot of code). And note VERY close on the 2nd page of the above, the heading is repeated.
So, I recommend you adopt a reporting system. The RDL and report designer is free, and is part of asp.net webforms. While the report writer and designer does have a learning curve, the above report was created without me having to write ANY code!!! Now, much of my previous experience is from desktop and MS-Access (which has the best report writer I have ever used). So, I at first found the RDL designer tools a bit of a challenge, but spend a day on learning this system, and then you have a VERY high quality reporting system that you can use for years. Better yet is the fantastic printer support, and even better is the automatic output to PDF. Over time, I suspect that you want additional reports, and using the GridiView is not designed for this purpose, hence your existing struggles.
Delete the marked parts in the figure.
headerTable.WriteSelectedRows(0, -1, document.LeftMargin, document.PageSize.Height - document.TopMargin, cb);
Best regards,
Lan Huang
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread