1

I am creating a pdf document. There is a PdfPTable in which some rows that will repeated in every page. What I want is to add page number in that table cell on each page.

I tried by rendering cell in PdfPageEventHelper and write table in onEndPage() but page number count is not increased and is always 1 in very page .

How can I achieve this?

[Updated]

I rendered table OnStartPage() instead of constructor. I used writer.PageNumber for pageCount. Page number is increased now but table is appeared again and again in every page.

public class itsEventsHandler : PdfPageEventHelper
{
 int pageCount;
 protected PdfPTable tblAccInfo = new PdfPTable(3);
 public itsEventsHandler()
 {

 }

 public override void OnStartPage(PdfWriter writer, Document document)
 {
      pageCount = writer.PageNumber;

      this.BuildBorderCell(tblAccInfo, "A/C No.", boldFont);
      this.BuildBorderCell(tblAccInfo, "External Doc No.", boldFont);
      this.BuildBorderCell(tblAccInfo, "PAGE", boldFont);

      this.BuildBorderCell(tblAccInfo, accountNo, titleFont);
      this.BuildBorderCell(tblAccInfo, docNo, titleFont);
      this.BuildBorderCell(tblAccInfo, pageCount.ToString(), titleFont);
  }


 public override void OnEndPage(PdfWriter writer, Document document)
 {
    tblAccInfo.WriteSelectedRows(0, -1, document.LeftMargin + 53f, 
    document.PageSize.Height - 250f, writer.DirectContent);
 }     

}

I expect the page number is in table cell on every page.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Zan
  • 31
  • 3
  • See https://stackoverflow.com/a/22808298/1729265 – mkl Apr 10 '19 at 05:24
  • Your `pageCount ++` is outside a method. Does your code compile at all? – mkl Apr 10 '19 at 05:32
  • Furthermore you build the table to use as header in the constructor using `pageCount.ToString()`. Thus, that value at construction time is fixed here... – mkl Apr 10 '19 at 05:35
  • thanks. I updated my code that I have tried. That time pagecount is increased but the table header is rendering again and again. – Zan Apr 10 '19 at 05:45
  • 1
    **A)** There is no need to use `OnStartPage`, you can do all that in `OnEndPage`. **B)** I see you adding new cells to the table `tblAccInfo` (at least I assume that's what `BuildBorderCell` does) for each page, so obviously it grows and grows and grows. Why don't you simply in `OnEndPage` instantiate a new `PdfPTable` instance, fill it, draw it, and drop it? – mkl Apr 10 '19 at 07:24
  • But how to drop the PdfPtable ? @mkl – Zan Apr 10 '19 at 07:54
  • 1
    By setting `tblAccInfo` to `null` or a new `PdfPTable` instance. – mkl Apr 10 '19 at 08:07
  • Thank you so much. I got it. @mkl – Zan Apr 10 '19 at 08:17
  • Please post your solution an answer. Or shall I make my comments into a more generic answer? – mkl Apr 10 '19 at 08:37
  • @mkl I already post the solution. – Zan Apr 10 '19 at 09:17

2 Answers2

1

This is my solution.

 public class itsEventsHandler : PdfPageEventHelper
 {
   int pageCount;
   protected PdfPTable tblAccInfo = new PdfPTable(3);
   public itsEventsHandler()
   {

   }

   public void BuildBorderCell(PdfPTable pdfTable, string strText, 
      iTextSharp.text.Font font)
   {
        PdfPCell cell = new PdfPCell(new Phrase(strText, font));
        cell.Border = iTextSharp.text.Rectangle.TOP_BORDER;
        cell.PaddingTop = 5f;
        pdfTable.AddCell(cell);
   }


   public override void OnEndPage(PdfWriter writer, Document document)
   {
     pageCount = writer.PageNumber;

     //Creating the table
     PdfPTable tblAccInfo = new PdfPTable(3);
     tblAccInfo.TotalWidth = 450f;

     float[] accInfoWidths = new float[] { 50f, 50f, 50f};
     tblAccInfo.SetWidths(accInfoWidths);

     //Building table cell
     BuildBorderCell(tblAccInfo, "A/C No.", boldFont);
     BuildBorderCell(tblAccInfo, "External Doc No.", boldFont);
     BuildBorderCell(tblAccInfo, "PAGE", boldFont);

     BuildBorderCell(tblAccInfo, accountNo, titleFont);
     BuildBorderCell(tblAccInfo, docNo, titleFont);
     BuildBorderCell(tblAccInfo, pageCount.ToString(), titleFont);

     //Writing the table
     tblAccInfo.WriteSelectedRows(0, -1, document.LeftMargin + 53f, 
     document.PageSize.Height - 250f, writer.DirectContent);

     //Droping the table
     tblAccInfo = null;
  }     

}
Zan
  • 31
  • 3
0

Instead of using the constructor you should override onStartPage ( https://itextsupport.com/apidocs/iText5/5.5.9/com/itextpdf/text/pdf/PdfPageEventHelper.html#onStartPage-com.itextpdf.text.pdf.PdfWriter-com.itextpdf.text.Document- )

There is a parameter document from type Document with a function getPageNumber (https://itextsupport.com/apidocs/iText5/5.5.9/com/itextpdf/text/Document.html#getPageNumber-- )

Edit

After reading links of @mkl I have to withdraw the above. Real answer is from @mkl in comment.

Mokuyobi
  • 160
  • 1
  • 9
  • Using `onStartPage` for adding content is recommended against by itext developers, even the api docs you refer to recommend the use of `OnEndPage`. And `OnEndPage` has the same `document` parameter... – mkl Apr 10 '19 at 05:30
  • Where does it say not to add content? `Note that if even if a page is not written this method is still called. It is preferable to use onEndPage to avoid infinite loops.` and `Note: do not use Document.add() inside a page event.` does not sound like you may not use the BuildBorderCell action OP uses. Also `OnPageEnd` has `document` parameter, OP used to use constructor instead of `OnPageEnd`and I though it was intentionally not to use it there. – Mokuyobi Apr 10 '19 at 05:42
  • I updated my code. I rendered the table OnStartPage() instead of the constructor. The pagecount is increased but the table is created one more in every page. – Zan Apr 10 '19 at 05:49
  • 2
    @Mokuyobi Ok, the API documentation only gives hints and is not very clear. In combination with what iText developers wrote here on stack overflow, though, it sums up to **"Don't add anything to the new document page in `onStartPage`, neither via `Document` nor via `PdfWriter` nor anyhow else, add content only in `onEndPage`. You can use `onStartPage` to prepare the content but beware, there are situations in which a page for which `onStartPage` has been called eventually is not needed and does not appear in the PDF."** – mkl Apr 10 '19 at 07:30
  • 2
    Read for example [this answer](https://stackoverflow.com/a/24064226/1729265) by Bruno Lowagie in which he more clearly announces it than in the ApiDocs or book: *you are adding content in the `OnStartPage()` method. That is forbidden!* – mkl Apr 10 '19 at 07:40
  • No problem. The mean thing is that adding content in `onStartPage` does work in 99% of the cases, but then suddenly that code results in some unwanted nearly empty pages inside your documents and you have no idea why... – mkl Apr 10 '19 at 08:36