I have an existing pdf file with multiple pages to which I would like to put a border to all pages.
So I create a class that inherits from PdfPageEventHelper and I override the OnEndPage and assign the instance of that class to the PageEvent of PdfWriter instance:
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace My.Apps.WPF.Classes
{
public class PdfEventHelper : PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document)
{
// Add border to page
PdfContentByte content = writer.DirectContent;
iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
rectangle.Left += document.LeftMargin;
rectangle.Right -= document.RightMargin;
rectangle.Top -= document.TopMargin;
rectangle.Bottom += document.BottomMargin;
content.SetColorStroke(BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
}
}
Then in main program I have a method that returns a new PDF with a border in all its pages (source pdf document 'pdfFilePath' is in landscape, so I keep orientation in new one):
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
PdfEventHelper pdfEvent = new PdfEventHelper();
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
writer.PageEvent = pdfEvent;
document.Open();
document.Close(); // here it crashes, see below in post exception thrown
writer.Close();
}
}
return newPdf;
}
In run-time, in line:
document.Close();
I get an IO.Exception that says:
The document has no pages.
In this case, Pdf document has only 1 page.
What am I doing wrong? I do not want to write anything to the existing pdf file, I only want to create a new PDF file exactly the same as source but with a border in all its pages.
UPDATE:
ATTEMPT #1:
I have done below, but I get all page in black (I do not know how to do the rectangle not filled):
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
int PageCount = reader.NumberOfPages;
for (int p = 1; p <= PageCount; p++)
{
// Add border to page
PdfContentByte cb = pdfStamper.GetOverContent(p);
iTextSharp.text.Rectangle rectangle = pdfReader.GetPageSizeWithRotation(p);
rectangle.BackgroundColor = iTextSharp.text.BaseColor.BLACK;
cb.Rectangle(rectangle);
}
}
}
}
return newPdf;
}
ATTEMPT #2:
In this attempt, I get an ObjectDisposedException:
Cannot access to a closed file.
when exiting the using of pdfStamper:
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
for (int p = 0; p < pdfStamper.Reader.NumberOfPages; p++)
{
// Add border to page
PdfContentByte content = writer.DirectContent;
iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
rectangle.Left += document.LeftMargin;
rectangle.Right -= document.RightMargin;
rectangle.Top -= document.TopMargin;
rectangle.Bottom += document.BottomMargin;
content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
document.Close();
writer.Close();
}
}
}
return newPdf;
}