C#,.net 8.0, iTextSharp 5.5.13.4 generate pdf with converting list<T> to table, Header with title and logo, footer with current page of total pages, add images proportionally
install-package iTextSharp --version 5.5.13.4; install-package System.Drawing.Common;
using iTextSharp.text; using iTextSharp.text.pdf; using Org.BouncyCastle.Bcpg.OpenPgp; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Metadata; using Document = iTextSharp.text.Document; using Font = iTextSharp.text.Font; using Image = iTextSharp.text.Image; namespace ConsoleApp21 { internal class Program { static List<Book> booksList = new List<Book>(); static string title = "SMOOTHTECH"; static string logoPath = @"C:\C\ConsoleApp21\ConsoleApp21\Images\logo.png"; static Font headerFont = new Font(Font.FontFamily.HELVETICA, 30, Font.BOLD, BaseColor.BLACK); static Font normalFont = new Font(Font.FontFamily.HELVETICA, 30, Font.NORMAL, BaseColor.BLACK); static void Main(string[] args) { InitBooksList(); string pdfFile = $"Export_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.pdf"; Task.Run(() => { Thread pdfThread = new Thread(() => { ExportListTDataToPDF(pdfFile, booksList); }); pdfThread.Start(); pdfThread.Join(); Console.WriteLine("Finished!"); var proc = new Process() { StartInfo=new ProcessStartInfo() { FileName = pdfFile, UseShellExecute = true } }; proc.Start(); }); Console.ReadLine(); } static void ExportListTDataToPDF<T>(string pdfFileName, List<T> dataList) { using (FileStream fileStream = new FileStream(pdfFileName, FileMode.Create)) { Document doc = new Document(PageSize.A1, 20, 20, 200, 50); PdfWriter writer = PdfWriter.GetInstance(doc, fileStream); writer.PageEvent=new PdfHeaderFooter(title, logoPath); doc.Open(); PopulateDataListToPDF(dataList, doc); string imgDir = @"../../../Images"; if(Directory.Exists(imgDir)) { var imgsList = Directory.GetFiles(imgDir).ToList(); if(imgsList!=null && imgsList.Any()) { PopulateImgsToPDF(imgsList, doc); } } doc.Close(); } } private static void PopulateImgsToPDF(List<string> imgsList, Document doc) { foreach(var imgFile in imgsList) { Image img = Image.GetInstance(imgFile); float availableWidth = doc.PageSize.Width - doc.LeftMargin - doc.RightMargin; float availableHeight = doc.PageSize.Height - doc.TopMargin - doc.BottomMargin; // Calculate scaling factors float widthRatio = availableWidth / img.Width; float heightRatio = availableHeight / img.Height; // Use the smaller scaling factor to maintain aspect ratio float scaleFactor = Math.Min(widthRatio, heightRatio); img.ScaleAbsolute(img.Width * scaleFactor, img.Height * scaleFactor); img.Alignment = Image.ALIGN_CENTER; doc.Add(img); } } private static void PopulateDataListToPDF<T>(List<T> dataList, Document doc) { float[] floatArr = new float[] { 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.4f }; PdfPTable table = new PdfPTable(floatArr); table.WidthPercentage= 100; var props = typeof(T).GetProperties(); var columnNames = props.Select(x => x.Name); foreach (var col in columnNames) { table.AddCell(new Phrase(col, headerFont)); } foreach (var item in dataList) { foreach (var prop in props) { string cellValue = prop.GetValue(item)?.ToString()??string.Empty; table.AddCell(new Phrase(cellValue, normalFont)); } } doc.Add(table); } static void InitBooksList() { for (int i = 0; i<1000; i++) { booksList.Add(new Book() { Id=i+1, Name=$"Name_{i+1}", Author=$"Author_{i+1}", ISBN=$"{Guid.NewGuid().ToString("N")}_{i+1}", Summary=$"Summary_{i+1}", Title=$"Title_{i+1}", Topic=$"Topic_{i+1}" }); } } } // Custom PageEventHelper for header and footer public class PdfHeaderFooter : PdfPageEventHelper { private readonly string title; private readonly string logoPath; private PdfTemplate totalPages; private BaseFont baseFont; public PdfHeaderFooter([Required]string title, string logoPath = null) { this.title = title; this.logoPath = logoPath; } public override void OnOpenDocument(PdfWriter writer, Document document) { baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); totalPages = writer.DirectContent.CreateTemplate(50, 50); } public override void OnStartPage(PdfWriter writer, Document document) { base.OnStartPage(writer, document); // Draw header PdfContentByte cb = writer.DirectContent; cb.BeginText(); // Title cb.SetFontAndSize(baseFont, 150); cb.SetRGBColorFill(0, 0, 0); cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, title, document.LeftMargin, document.PageSize.Height-150, 0); // Logo (if provided) if (!string.IsNullOrEmpty(logoPath) && File.Exists(logoPath)) { try { Image logo = Image.GetInstance(logoPath); logo.ScaleToFit(150, 150); logo.SetAbsolutePosition(document.PageSize.Width - document.RightMargin - 120, document.PageSize.Height - 150); cb.AddImage(logo); } catch (Exception ex) { Console.WriteLine($"Error loading logo: {ex.Message}"); } } cb.EndText(); //Header Line height cb.SetLineWidth(20); cb.SetColorStroke(new BaseColor(Color.Cyan)); // Draw header line cb.MoveTo(document.LeftMargin, document.PageSize.Height - 180); cb.LineTo(document.PageSize.Width - document.RightMargin, document.PageSize.Height - 180); cb.Stroke(); } public override void OnEndPage(PdfWriter writer, Document document) { base.OnEndPage(writer, document); PdfContentByte cb = writer.DirectContent; cb.BeginText(); cb.SetFontAndSize(baseFont, 30); cb.SetRGBColorFill(0, 0, 0); // Footer with page numbers (current page / total pages) string footerText = $"{writer.PageNumber}/"; float textWidth = baseFont.GetWidthPoint(footerText, 30); cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, footerText, (document.GetRight(0) + textWidth)/2, document.BottomMargin - 20, 0); // Add total pages placeholder cb.AddTemplate(totalPages, (document.GetRight(0) + textWidth)/2+20, document.BottomMargin - 20); cb.EndText(); // Draw footer line cb.SetLineWidth(2); cb.MoveTo(document.LeftMargin, document.BottomMargin - 10); cb.LineTo(document.PageSize.Width - document.RightMargin, document.BottomMargin - 10); cb.Stroke(); } public override void OnCloseDocument(PdfWriter writer, Document document) { base.OnCloseDocument(writer, document); // Set total pages count in the template totalPages.BeginText(); totalPages.SetFontAndSize(baseFont, 30); totalPages.SetRGBColorFill(0, 0, 0); totalPages.ShowText((writer.PageNumber).ToString()); totalPages.EndText(); } } public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public string Summary { get; set; } public string Title { get; set; } public string Topic { get; set; } public string ISBN { get; set; } } }