Install-Package iTextSharp;
Install-Package System.Drawing.Common;
static void ExportDataListAndImageInPDFWithHeaderFooter<T>(string pdfFile, List<string> imgsList, List<T> dataList) where T : class
{
string pdfTitle = "SMOOTHTECH";
string iconPath = @"../../../Images/logo.png";
try
{
Stopwatch watch = Stopwatch.StartNew();
if (!File.Exists(pdfFile))
{
using (FileStream fileStream = new FileStream(pdfFile, FileMode.Create))
{
using (Document doc = new Document(PageSize.A1, 36, 36, 144, 72))
{
using (PdfWriter pdfWriter = PdfWriter.GetInstance(doc, fileStream))
{
//Add header and footer
var pdfHeaderFooter = new PdfHeaderFooter(pdfTitle, iconPath);
pdfWriter.PageEvent=pdfHeaderFooter;
doc.Open();
PopulateDataListInPDF(dataList, watch, doc);
doc.Close();
}
}
}
}
else
{
//Append mode
string tempFile = Path.GetTempFileName();
//Copy existing pages
using (PdfReader pdfReader = new PdfReader(pdfFile))
{
using (FileStream fileStream = new FileStream(tempFile, FileMode.Create))
{
using (Document doc = new Document(pdfReader.GetPageSizeWithRotation(1)))
{
using (PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(doc, fileStream))
{
doc.Open();
//Copy old pages
for (int i = 1; i<=pdfReader.NumberOfPages; i++)
{
pdfSmartCopy.AddPage(pdfSmartCopy.GetImportedPage(pdfReader, i));
}
//Generate a temporary PDF with your new table
using (MemoryStream ms = new MemoryStream())
{
using (Document tempDoc = new Document(PageSize.A1, 36, 36, 144, 72))
{
using (PdfWriter pdfWriter = PdfWriter.GetInstance(tempDoc, ms))
{
//Add header and footer
var pdfHeaderFooter = new PdfHeaderFooter(pdfTitle, iconPath);
pdfWriter.PageEvent=pdfHeaderFooter;
tempDoc.Open();
watch.Restart();
PopulateDataListInPDF(newBooksList, watch, tempDoc);
tempDoc.Close();
}
//Reopen temp doc and import its pages
using (PdfReader tempReaer = new PdfReader(ms.ToArray()))
{
for (int i = 1; i<=tempReaer.NumberOfPages; i++)
{
pdfSmartCopy.AddPage(pdfSmartCopy.GetImportedPage(tempReaer, i));
}
}
}
}
doc.Close();
}
}
}
}
File.Delete(pdfFile);
File.Move(tempFile, pdfFile);
File.Delete(tempFile);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace?.ToString());
}
}
private static void PopulateDataListInPDF<T>(List<T> dataList, Stopwatch watch, Document doc) where T : class
{
//public static Font GetFont(string fontname, float size, int style, BaseColor color)
var cellFont = FontFactory.GetFont(FontFactory.HELVETICA, 20f, (int)(FontStyle.Regular), BaseColor.BLACK);
var props = typeof(T).GetProperties();
int propsCount = props.Count();
//header
PdfPTable table = new PdfPTable(propsCount);
table.WidthPercentage=100;
foreach (var prop in props)
{
var headerCell = new PdfPCell(new Phrase(prop.Name, FontFactory.GetFont(FontFactory.HELVETICA, 20f, (int)(FontStyle.Bold), BaseColor.BLACK)))
{
BackgroundColor=BaseColor.LIGHT_GRAY,
HorizontalAlignment=Element.ALIGN_CENTER
};
table.AddCell(headerCell);
}
//data
int rowCount = 0;
foreach (var item in dataList)
{
foreach (var prop in props)
{
string cellValue = prop.GetValue(item)?.ToString()??"";
var pdfCell = new PdfPCell(new Phrase(cellValue, cellFont))
{
HorizontalAlignment=Element.ALIGN_LEFT,
VerticalAlignment=Element.ALIGN_CENTER,
Padding=2
};
table.AddCell(pdfCell);
}
if (++rowCount%docInterval==0)
{
doc.Add(table);
table = new PdfPTable(propsCount);
table.WidthPercentage=100;
Console.WriteLine($"{rowCount} processed time cost:{watch.Elapsed.TotalSeconds},{GetProcessMemory()} M");
}
}
//add the remaining
if (rowCount%docInterval!=0)
{
doc.Add(table);
}
Console.WriteLine($"{rowCount},total time cost:{watch.Elapsed.TotalSeconds},{GetProcessMemory()} M");
}
static string GetProcessMemory()
{
var proc = Process.GetCurrentProcess();
return $"{(proc.WorkingSet64/1024/1024)}";
}
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Diagnostics;
using System.Drawing;
using Document = iTextSharp.text.Document;
using Font = iTextSharp.text.Font;
using Image = iTextSharp.text.Image;
namespace ConsoleApp36
{
internal class Program
{
static List<Book> booksList = new List<Book>();
static List<Book> newBooksList = new List<Book>();
static int startIdx = 0;
static int interval = 1000;
static int docInterval = 100;
static void Main(string[] args)
{
ExportBooksListInPDFDemo();
}
static void ExportBooksListInPDFDemo()
{
InitBooksList();
InitNewBooksList();
string pdfFile = $"Book_Output.pdf";
ExportDataListAndImageInPDFWithHeaderFooter(pdfFile, null, booksList);
ExportDataListAndImageInPDFWithHeaderFooter(pdfFile, null, newBooksList);
Console.WriteLine($"Exported as {pdfFile}");
}
static void InitBooksList()
{
int endIdx = startIdx+interval;
while (startIdx< endIdx)
{
int i = ++startIdx;
booksList.Add(new Book()
{
Id=i,
Name=$"Name_{i}",
Author=$"Author_{i}",
Comment=$"Comment_{i}",
Description=$"Description_{i}",
Summary=$"Summary_{i}",
Title=$"Title_{i}",
Topic=$"Topic_{i}",
ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
});
}
}
static void InitNewBooksList()
{
int endIdx = startIdx+interval;
while (startIdx< endIdx)
{
int i = ++startIdx;
newBooksList.Add(new Book()
{
Id=i,
Name=$"Name_{i}",
Author=$"Author_{i}",
Comment=$"Comment_{i}",
Description=$"Description_{i}",
Summary=$"Summary_{i}",
Title=$"Title_{i}",
Topic=$"Topic_{i}",
ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
});
}
}
static void ExportDataListAndImageInPDFWithHeaderFooter<T>(string pdfFile, List<string> imgsList, List<T> dataList) where T : class
{
string pdfTitle = "SMOOTHTECH";
string iconPath = @"../../../Images/logo.png";
try
{
Stopwatch watch = Stopwatch.StartNew();
if (!File.Exists(pdfFile))
{
using (FileStream fileStream = new FileStream(pdfFile, FileMode.Create))
{
using (Document doc = new Document(PageSize.A1, 36, 36, 144, 72))
{
using (PdfWriter pdfWriter = PdfWriter.GetInstance(doc, fileStream))
{
//Add header and footer
var pdfHeaderFooter = new PdfHeaderFooter(pdfTitle, iconPath);
pdfWriter.PageEvent=pdfHeaderFooter;
doc.Open();
PopulateDataListInPDF(dataList, watch, doc);
doc.Close();
}
}
}
}
else
{
//Append mode
string tempFile = Path.GetTempFileName();
//Copy existing pages
using (PdfReader pdfReader = new PdfReader(pdfFile))
{
using (FileStream fileStream = new FileStream(tempFile, FileMode.Create))
{
using (Document doc = new Document(pdfReader.GetPageSizeWithRotation(1)))
{
using (PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(doc, fileStream))
{
doc.Open();
//Copy old pages
for (int i = 1; i<=pdfReader.NumberOfPages; i++)
{
pdfSmartCopy.AddPage(pdfSmartCopy.GetImportedPage(pdfReader, i));
}
//Generate a temporary PDF with your new table
using (MemoryStream ms = new MemoryStream())
{
using (Document tempDoc = new Document(PageSize.A1, 36, 36, 144, 72))
{
using (PdfWriter pdfWriter = PdfWriter.GetInstance(tempDoc, ms))
{
//Add header and footer
var pdfHeaderFooter = new PdfHeaderFooter(pdfTitle, iconPath);
pdfWriter.PageEvent=pdfHeaderFooter;
tempDoc.Open();
watch.Restart();
PopulateDataListInPDF(newBooksList, watch, tempDoc);
tempDoc.Close();
}
//Reopen temp doc and import its pages
using (PdfReader tempReaer = new PdfReader(ms.ToArray()))
{
for (int i = 1; i<=tempReaer.NumberOfPages; i++)
{
pdfSmartCopy.AddPage(pdfSmartCopy.GetImportedPage(tempReaer, i));
}
}
}
}
doc.Close();
}
}
}
}
File.Delete(pdfFile);
File.Move(tempFile, pdfFile);
File.Delete(tempFile);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace?.ToString());
}
}
private static void PopulateDataListInPDF<T>(List<T> dataList, Stopwatch watch, Document doc) where T : class
{
//public static Font GetFont(string fontname, float size, int style, BaseColor color)
var cellFont = FontFactory.GetFont(FontFactory.HELVETICA, 20f, (int)(FontStyle.Regular), BaseColor.BLACK);
var props = typeof(T).GetProperties();
int propsCount = props.Count();
//header
PdfPTable table = new PdfPTable(propsCount);
table.WidthPercentage=100;
foreach (var prop in props)
{
var headerCell = new PdfPCell(new Phrase(prop.Name, FontFactory.GetFont(FontFactory.HELVETICA, 20f, (int)(FontStyle.Bold), BaseColor.BLACK)))
{
BackgroundColor=BaseColor.LIGHT_GRAY,
HorizontalAlignment=Element.ALIGN_CENTER
};
table.AddCell(headerCell);
}
//data
int rowCount = 0;
foreach (var item in dataList)
{
foreach (var prop in props)
{
string cellValue = prop.GetValue(item)?.ToString()??"";
var pdfCell = new PdfPCell(new Phrase(cellValue, cellFont))
{
HorizontalAlignment=Element.ALIGN_LEFT,
VerticalAlignment=Element.ALIGN_CENTER,
Padding=2
};
table.AddCell(pdfCell);
}
if (++rowCount%docInterval==0)
{
doc.Add(table);
table = new PdfPTable(propsCount);
table.WidthPercentage=100;
Console.WriteLine($"{rowCount} processed time cost:{watch.Elapsed.TotalSeconds},{GetProcessMemory()} M");
}
}
//add the remaining
if (rowCount%docInterval!=0)
{
doc.Add(table);
}
Console.WriteLine($"{rowCount},total time cost:{watch.Elapsed.TotalSeconds},{GetProcessMemory()} M");
}
static string GetProcessMemory()
{
var proc = Process.GetCurrentProcess();
return $"{(proc.WorkingSet64/1024/1024)}";
}
}
public class PdfHeaderFooter : PdfPageEventHelper
{
private PdfTemplate totalPages;
private BaseFont baseFont;
private string logoTitle;
private string logoPath;
private BaseColor baseColor = new BaseColor(64, 128, 128, 255);
public PdfHeaderFooter(string logoTitleValue = "SMOOTHTECH", string logoPathValue = @"../../../Images/logo.png")
{
logoTitle = logoTitleValue;
this.logoPath = logoPathValue;
}
public override void OnOpenDocument(PdfWriter writer, Document document)
{
baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, false);
totalPages = writer.DirectContent.CreateTemplate(50, 50);
}
public override void OnEndPage(PdfWriter writer, Document document)
{
var cb = writer.DirectContent;
// --- HEADER ---
float leftMargin = document.LeftMargin;
float rightMargin = document.RightMargin;
float pageWidth = document.PageSize.Width;
float usableWidth = pageWidth - leftMargin - rightMargin;
// Draw title
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
new Phrase(logoTitle, new Font(Font.FontFamily.HELVETICA, 50, Font.BOLD, baseColor)),
document.LeftMargin, document.Top + 30, 0);
// Draw logo (right aligned)
if (File.Exists(logoPath))
{
var logoImg = Image.GetInstance(logoPath);
logoImg.ScaleToFit(70, 70);
logoImg.SetAbsolutePosition(pageWidth - rightMargin - logoImg.ScaledWidth, document.Top + 10);
cb.AddImage(logoImg);
}
// Line below header
cb.SetLineWidth(10f);
cb.SetColorStroke(baseColor);
cb.MoveTo(leftMargin, document.Top);
cb.LineTo(pageWidth - rightMargin, document.Top);
cb.Stroke();
// --- FOOTER ---
float footerY = document.Bottom - 40;
// Line above footer
cb.SetLineWidth(10f);
cb.SetColorStroke(baseColor);
cb.MoveTo(leftMargin, footerY + 30);
cb.LineTo(pageWidth - rightMargin, footerY + 30);
cb.Stroke();
// Page number: X/Y
string text = "" + writer.PageNumber + "/";
float len = baseFont.GetWidthPoint(text, 12);
cb.BeginText();
cb.SetFontAndSize(baseFont, 12);
cb.SetTextMatrix(pageWidth / 2 - 30, footerY);
cb.ShowText(text);
cb.EndText();
cb.AddTemplate(totalPages, pageWidth / 2 - 30 + len, footerY);
}
public override void OnCloseDocument(PdfWriter writer, Document document)
{
totalPages.BeginText();
totalPages.SetFontAndSize(baseFont, 12);
totalPages.SetTextMatrix(0, 0);
totalPages.ShowText("" + (writer.PageNumber));
totalPages.EndText();
}
}
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Comment { get; set; }
public string Description { get; set; }
public string Summary { get; set; }
public string Title { get; set; }
public string Topic { get; set; }
public string ISBN { get; set; }
}
}