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;

image

 

 

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; }
    }
}

 

 

 

image

 

image

 

image

 

posted @ 2025-08-26 18:03  FredGrit  阅读(9)  评论(0)    收藏  举报