3

I want to get the first and second column height to know if I need to call document.NewPage() or not. But, I can't find a way to do this without adding the table to the document.

Example:

PdfPRow firstRow = new PdfPRow(cells1.ToArray());
table.Rows.Add(firstRow);
PdfPRow secondRow = new PdfPRow(cells2.ToArray());
table.Rows.Add(secondRow);

float h1 = table.GetRowHeight(0), h2 = table.GetRowHeight(1);

if (currentY - h1 - h2 < 30) document.NewPage();

document.Add(table);
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Emanuel
  • 6,622
  • 20
  • 58
  • 78

4 Answers4

4

See my answer here. Basically, you can't know the dimensions of a table until it renders. However, you can render the table to a document that you just throw away and then re-render it later.

Community
  • 1
  • 1
Chris Haas
  • 53,986
  • 12
  • 141
  • 274
2

Unless you set the width of the table, table.GetRowHeight(0) will always return zero.

// added
table.TotalWidth = 400f;     
//
PdfPRow firstRow = new PdfPRow(cells1.ToArray());

table.Rows.Add(firstRow);
PdfPRow secondRow = new PdfPRow(cells2.ToArray());
table.Rows.Add(secondRow);

float h1 = table.GetRowHeight(0), h2 = table.GetRowHeight(1);

if (currentY - h1 - h2 < 30) document.NewPage();

document.Add(table);
lvs ravi
  • 21
  • 1
2

There is another way to do this: Create the table at first.

    this.table = new PdfPTable(relativeColumnWidths);
    this.table.SetTotalWidth(absoluteColumnWidths);
    this.rowCells.Clear();

You may now fill the List with table cells:

    Paragraph pText = new Paragraph(text, this.font);
    PdfPCell cell = new PdfPCell(pText);
    this.rowCells.Add(cell);

When you are ready to create the new row:

    PdfPRow row = new PdfPRow(this.rowCells.ToArray());
    this.table.Rows.Add(row);

This is nothing special. But if you now set the table width again, you are able to calculate the row height properly:

    this.table.SetTotalWidth(this.table.AbsoluteWidths);
    this.rowCells.Clear();
    float newRowsHeight = this.table.GetRowHeight(this.table.Rows.Count - 1);

If the row is not fitting your conditions you can simply remove it from the rows collection of the table. The total height of the table will be calculated properly also.

2

Interesting question, so +1. And already marked as answered, but...

"But, I can't find a way to do this without adding the table to the document."

It is possible. Wrap the PdfPTable in a ColumnText object and take advantage of the ColumnText.Go() overload to get the total height of any arbitrary/number of rows you want without adding the PdfPTable to the Document. Here's a simple helper method:

public static float TotalRowHeights(
  Document document, PdfContentByte content, 
  PdfPTable table, params int[] wantedRows) 
{
  float height = 0f;
  ColumnText ct = new ColumnText(content);
// respect current Document.PageSize    
  ct.SetSimpleColumn(
    document.Left, document.Bottom, 
    document.Right, document.Top
  );
  ct.AddElement(table);
// **simulate** adding the PdfPTable to calculate total height
  ct.Go(true);
  foreach (int i in wantedRows) {
    height += table.GetRowHeight(i);
  }
  return height;
}

And a simple use case tested with 5.2.0.0:

using (Document document = new Document()) {
  PdfWriter writer = PdfWriter.GetInstance(document, STREAM);
  document.Open();
  PdfPTable table = new PdfPTable(4);
  for (int i = 1; i < 20; ++i) {
    table.AddCell(i.ToString());
  }
  int[] wantedRows = {0, 2, 3};
  document.Add(new Paragraph(string.Format(
    "Simulated table height: {0}",
    TotalRowHeights(document, writer.DirectContent, table, wantedRows)
  )));
// uncomment block below to verify correct height is being calculated
/* 
  document.Add(new Paragraph("Add the PdfPTable"));
  document.Add(table);
  float totalHeight = 0f;
  foreach (int i in wantedRows) {
    totalHeight += table.GetRowHeight(i);
  }
  document.Add(new Paragraph(string.Format(
    "Height after adding table: {0}", totalHeight
  )));
*/
  document.Add(new Paragraph("Test paragraph"));
}

In the use case rows 1, 3, and 4 are used, but only to demonstrate any combination/number of rows will work.

kuujinbo
  • 9,272
  • 3
  • 44
  • 57