Reputation: 14484
I have a PDF generated using iTextSharp that displays a "Page 1/4" etc. thing in the footer. This all works fine and is implemented using a PdfTemplate
that is set in the OnEndPage()
method with the total number of pages added in the OnCloseDocument()
method.
What I would like to do is remove this if there is only one page in the document. I've tried this in my OnCloseDocument()
method, but it doesn't actually remove the template:
public override void OnCloseDocument(PdfWriter writer, Document document)
{
base.OnCloseDocument(writer, document);
if (writer.PageNumber >= 3)
{
template.BeginText();
template.SetFontAndSize(f_cn, CocService.footerFont.Size);
template.SetTextMatrix(0, 0);
template.ShowText("" + (writer.PageNumber - 1));
template.EndText();
}
else
{
template.Reset();
}
}
Just for reference, here's the relevant code from the OnEndPage()
method:
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
int pageN = writer.PageNumber;
String text = "Page " + pageN.ToString() + "/";
float len = f_cn.GetWidthPoint(text, CocService.footerFont.Size);
iTextSharp.text.Rectangle pageSize = document.PageSize;
cb.SetRGBColorFill(100, 100, 100);
cb.BeginText();
cb.SetFontAndSize(f_cn, CocService.footerFont.Size);
cb.SetTextMatrix(document.LeftMargin+520, pageSize.GetBottom(document.BottomMargin)+33);
cb.ShowText(text);
cb.EndText();
cb.AddTemplate(template, document.LeftMargin + 520 + len, pageSize.GetBottom(document.BottomMargin)+33);
}
Upvotes: 2
Views: 4239
Reputation: 77528
You are already writing text to the content stream in your onEndPage()
method, and there's no way to remove that after the fact because that stream may already have been sent to the OutputStream
.
The best way to avoid having any page numbers on a document if there's only one page, is to add page numbers in a second go. Take a look at the TwoPasses example, especially where it says "SECOND PASS". IMO, this is the most elegant way to solve your problem. Ask the reader
for the number of pages. If it's 1, do nothing. If it's more, add page X of Y.
By the way: for the C# port of the examples, go to http://tinyurl.com/itextsharpIIA2C06
Upvotes: 1
Reputation: 14484
The solution I ended up going with was adding a separate PdfTemplate
object to each page, then setting all the page numbers (or leaving them out altogether) in the OnCloseDocument()
method. I thought this was pretty elegant too. Here's the essential code:
// Inner class for dealing with the page numbering
class CocPdfEventHelper : PdfPageEventHelper
{
List<PdfTemplate> pageNumberTemplates = new List<PdfTemplate>();
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
// Add a unique (empty) template for each page here
PdfTemplate t = writer.DirectContent.CreateTemplate(180, 50);
pageNumberTemplates.Add(t);
writer.DirectContent.AddTemplate(t, document.LeftMargin + 520, document.PageSize.GetBottom(document.BottomMargin) + 33);
}
public override void OnCloseDocument(PdfWriter writer, Document document)
{
base.OnCloseDocument(writer, document);
// Only bother if there is more than 1 page
if (writer.PageNumber >= 3)
{
int count = 1;
foreach (PdfTemplate template in pageNumberTemplates)
{
template.BeginText();
template.SetFontAndSize(f_cn, CocService.footerFont.Size);
template.SetRGBColorFill(100, 100, 100);
template.SetTextMatrix(0,0);
template.ShowText("Page " + count + " of " + (writer.PageNumber - 1));
template.EndText();
count++;
}
}
}
}
Upvotes: 4