向每个页面添加表行计数 [英] Add table row counts to every page

查看:108
本文介绍了向每个页面添加表行计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用iTextSharp获取每页写入PdfPTable的总行数?

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

我想把我的所有代码的OnStartPage

public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper
{
    public override void OnStartPage(PdfWriter writer, Document document)
    {
        /// my code
    }
}


推荐答案

正如布鲁诺所说,你想要研究 IPdfPTableEvent 。该特定接口的缺点是它在每个页面上都被调用,只有正在打印到该特定页面的表的副本。因此,如果您有一个200行表,在第一页上,您可能只看到一个包含50行的表,而您永远不知道总行数。然而,有一个是派生从它所谓的 IPdfPTableEventSplit 也会收到原始表的副本,这正是您所需要的。

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.

一个非常重要的注意事项是,如果一个表没有拆分那么永远不会调用 SplitTable 。我在 TableLayout 方法中通过检查我们的默认行数 -1 是否已更改为其他。

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();
        }
    }
}

这篇关于向每个页面添加表行计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆