0

How can I get the total number of rows written to a PdfPTable for every page using iTextSharp?

I want to put all of my code onStartPage

public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper
{
    public override void OnStartPage(PdfWriter writer, Document document)
    {
        /// my code
    }
}
Chris Haas
  • 53,986
  • 12
  • 141
  • 274
Mohammad.Kaab
  • 1,025
  • 7
  • 20
  • What is "page total rows"? Are you trying to do a "page X of Y"? http://stackoverflow.com/a/9845722/231316 – Chris Haas May 02 '14 at 14:18
  • Yes, follow that example, and the example it refers to: http://itextpdf.com/examples/iia.php?id=104 **Never** add content in the `OnStartPage()` method. That's **not** what that method is for. – Bruno Lowagie May 02 '14 at 14:52
  • If, on the other hand, you're talking about tables (what else would you mean by "total rows"?), you'll need a `PdfPTableEvent`. In any case: your question isn't clear. Saying *"i want to put all of my code onStartPage"* doesn't make sense. You should update your question if you want help. – Bruno Lowagie May 02 '14 at 14:54
  • i mean , how can i get the total rows in each page . lets says that the first page has 40 row , okay , now i want to do something to write the total number of the rows in the footer . like - 40 - and now let's say the total rows in the second page is 30 then ... and for other pages too . so any sulation – Mohammad.Kaab May 02 '14 at 15:32

1 Answers1

1

As Bruno said you'll want to look into IPdfPTableEvent. The downside of that specific interface is that it gets called on every page with only a copy of the table that's being printed to that specific page. So if you have a 200 row table, on page one you might only see a table with 50 rows and you never know the total row count. However, there's a more interesting interface that derives from it called IPdfPTableEventSplit which receives a copy of the original table, too, which is what you're looking for.

Below is a basic implementation of that interface. You might need to apply some additional logic to account for headers but it should be relatively easy. I'm also writing to the bottom of the page but you'll probably want to adjust that.

One very important note is that if a table doesn't split then the SplitTable is never called. I account for this in the TableLayout method by checking to see if our default row count of -1 has been changed to something else.

public class TableRowCounter : IPdfPTableEventSplit {
    /// <summary>
    /// Will hold the total number of rows in the table if a split occurs,
    /// or negative one if no split happened.
    /// </summary>
    private int totalRowCount = -1;

    /// <summary>
    /// Holds the number of rows previously processed
    /// </summary>
    private int currentRowIndex = 0;

    /// <summary>
    /// Called if/when a table split happens
    /// </summary>
    /// <param name="table"></param>
    public void SplitTable(PdfPTable table) {
        this.totalRowCount = table.Rows.Count;
    }

    public void TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) {
        //Count the number of rows processed in this iteration
        var thisRowCount = table.Rows.Count;

        //Get one of the canvases to draw on. You could also use one of these
        //PdfPTable.BACKGROUNDCANVAS or PdfPTable.LINECANVAS or PdfPTable.TEXTCANVAS 
        var writer = canvases[PdfPTable.BASECANVAS].PdfWriter;

        //Create our text
        var txt = String.Format(
            "Showing rows {0} through {1} of {2} total rows",
            (currentRowIndex + 1),                                  //Zero-based index convert to one-based
            (currentRowIndex + thisRowCount),   
            ( -1 == totalRowCount ? thisRowCount : totalRowCount)   //If a table split doesn't occur then our class variable won't be reset, just use the local count
            );

        //Draw our text
        ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, new Phrase(txt), 10, 10, 0);

        //Increment our total row count
        currentRowIndex += table.Rows.Count;
    }
}

A very simple implementation of this code would be:

var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");

using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            var t = new PdfPTable(1);

            //Bind an instance of our table counter to the table event
            t.TableEvent = new TableRowCounter();
            for (var i = 1; i < 500; i++) {
                t.AddCell(i.ToString());
            }

            doc.Add(t);

            doc.Close();
        }
    }
}
Chris Haas
  • 53,986
  • 12
  • 141
  • 274