问题描述
如何使用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
}
}
推荐答案
正如布鲁诺所说,你想要研究 。该特定接口的缺点是它在每个页面上都被调用,只有正在打印到该特定页面的表的副本。因此,如果您有一个200行表,在第一页上,您可能只看到一个包含50行的表,而您永远不知道总行数。然而,有一个是派生从它所谓的也会收到原始表的副本,这正是您所需要的。
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();
}
}
}
这篇关于向每个页面添加表行计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!