Click here to Skip to main content
16,017,297 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
Hi,

I have a data driven report where the user can select items (columns) to include.

If the user selects a lot, the text in the cells of the PdfPTable wraps and can get so tall that I hit the infinite loop error as the row content will not fit on the page.

Fair enough. I'll loop through and check the height of all my rows before attempting to add the PdfPTable to the Document object. If any row has a greater height that my pagesize height (-header row) I'll tell the user to deselect some items.

The Pagesize is always A4 landscape. But I'm having a units confusion.

When I can still fit 3 rows on the page, oPDFTable.GetRowHeight() returns heights of 1220,2100,1892.

Yet the Pagesize height is only 595?

What units does GetRowHeight() Return?

How can I tell when a row is too tall to fit on the page?

Grateful for any advice
Posted

Here's part of a report I wrote in which I address the exact problem you face. I looks like I used PdfPTable.TotalHeight.

Units are always Postscript points, except for font metrics.

#region Build the report
// create a queue for the items
var queue = new Queue<ProductionReportSchema.Production_BuilderRow>(_Orders.Count);
foreach (var row in _Orders)
    queue.Enqueue(row);

PdfPTable table = null;
var page = 1;
for (ProductionReportSchema.Production_BuilderRow row = null; queue.Count > 0; )
{
    row = queue.Peek();
    if (table == null)
    {
        document.NewPage();
        content.BeginText();
        content.SetFontAndSize(courierbold, 12);
        content.ShowTextAligned(left, "Production Report - Batch " + Batch, 36, 564, 0);
        content.ShowTextAligned(centre, DateTime.Now.ToString(), 396, 564, 0);
        content.ShowTextAligned(right, "Page " + page++, 756, 564, 0);
        content.EndText();

        table = new PdfPTable(10);
        table.SetTotalWidth(new float[] { 24, 24, 50, 50, 50, 72, 72, 72, 24, 288 });
        table.DefaultCell.HorizontalAlignment = centre;
        table.AddCell(new Phrase("Done", GridBoldStyle));
        table.AddCell(new Phrase("0-9", GridBoldStyle));
        table.AddCell(new Phrase("B", GridBoldStyle));
        table.AddCell(new Phrase("Order", GridBoldStyle));
        table.AddCell(new Phrase("Line", GridBoldStyle));
        table.AddCell(new Phrase("Item", GridBoldStyle));
        table.AddCell(new Phrase("Colour", GridBoldStyle));
        table.AddCell(new Phrase("Icon", GridBoldStyle));
        table.AddCell(new Phrase("Qty", GridBoldStyle));
        table.DefaultCell.HorizontalAlignment = left;
        table.DefaultCell.VerticalAlignment = top;
        table.AddCell(new Phrase("Name", GridBoldStyle));
        table.CompleteRow();
    }

    table.DefaultCell.PaddingBottom = 0;
    table.DefaultCell.Border = Rectangle.NO_BORDER;
    table.DefaultCell.BorderWidthTop = 0.25f;
    table.DefaultCell.HorizontalAlignment = centre;
    var box = new PdfPCell(table.DefaultCell);
    box.AddElement(row.Quantity == 1 ? checkbox : doublecheckbox);
    table.AddCell(box); // done
    table.AddCell(new Phrase(row.Priority.ToString(), GridStyle)); // priority
    table.AddCell(new Phrase("B" + row.id, GridStyle)); // b#
    table.AddCell(new Phrase("O" + row.OrderNo, GridStyle)); // order no
    table.AddCell(new Phrase("L" + row.ODid, GridStyle)); // line#
    table.AddCell(new Phrase(row.ItemNo, GridStyle)); // item
    if (row.IsColourNull())
        table.AddCell(string.Empty);
    else
    {
        var ColourRow = Globals.Standards.Colours.FindByid(row.Colour);
        table.AddCell(new Phrase(ColourRow == null ? string.Empty : ColourRow.Name_en, GridStyle)); // colour
    }
    if (row.IsIconNull())
        table.AddCell(string.Empty);
    else
    {
        var IconRow = Globals.Standards.Icons.FindByCode((short)row.Icon);
        table.AddCell(new Phrase(IconRow == null ? string.Empty : IconRow.Name_en, GridStyle)); // icon
    }
    table.AddCell(new Phrase(row.Quantity.ToString(), GridStyle)); // qty

    table.DefaultCell.HorizontalAlignment = centre;
    // make barcodes
    var texts =  new List<string>();

    var xml = new XmlDocument();
    var valid = true;
    try { xml.LoadXml(row.MetaXml); }
    catch (XmlException) { valid = false; }

    // for granular group items
    var xpath1 = string.Format("//SubItem[@Code='{0}']", row.ItemNo);
    var node1 = xml.SelectSingleNode(xpath1);
    // for items with text embedded in XML
    var nodes2 = xml.SelectNodes("//Text");

    if (valid && node1 != null && node1.Attributes["GranularGroup"] == null)
    {
        foreach (XmlNode child in node1.ChildNodes)
            if (child.Name == "Text")
                texts.Add(child.InnerText);
    }
    else if (nodes2.Count != 0)
    {
        foreach (XmlNode node in nodes2)
        {
            texts.Add(node.InnerText);
            if (nodes2.Count > 10 && node == nodes2[9])
                break;
        }
    }
    else
    {
        var TextLines = Regex.Matches(row.Name, @"(?<Output>.+?)(?<EOL>\|\||\r?\n|$)", RegexOptions.Multiline);
        foreach (Match match in TextLines)
            texts.Add(match.Groups["Output"].Value);
    }

    var TextCell = new PdfPCell(table.DefaultCell);
    foreach (var text in texts)
        if (Text.IsPrintable(text))
        {
            var barcode = new Barcode128();
            barcode.Font = courier;
            barcode.BarHeight = 12;
            barcode.Code = text;
            barcode.TextAlignment = left;
            var bi = barcode.CreateImageWithBarcode(content, black, black);
            bi.ScalePercent(100);
            TextCell.AddElement(bi); // name
        }
        else
            TextCell.AddElement(new Phrase(text, GridStyle)); // name
    table.AddCell(TextCell);

    // If it fits, commit the row we just added
    if (table.TotalHeight <= 500)
    {
        table.CompleteRow();
        // a row just for comments
        table.DefaultCell.PaddingBottom = 10;
        table.DefaultCell.BorderWidthTop = 0f;
        var CommentCell = new PdfPCell(table.DefaultCell);
        CommentCell.AddElement(new Phrase(row.Comments, GridStyle));
        CommentCell.Colspan = 10;
        table.AddCell(CommentCell);
        table.CompleteRow();
        queue.Dequeue();
    }
    else
    {
        table.DeleteLastRow();
        table.WriteSelectedRows(0, -1, 36, 540, content);
        table = null;
    }
}
if(table != null)
    table.WriteSelectedRows(0, -1, 36, 540, content);

document.Close();
var PdfViewer = new PdfViewer();
PdfViewer.Filename = filename;
PdfViewer.Show();
#endregion
 
Share this answer
 
Comments
brian_bloke 8-Jun-11 9:13am    
Thanks. But there's still something else going on here. My table has 300 rows, TotalHeight of 413006. First few rows fit on a page then paginates as expected. pageheight is 595, first four rowheights from getrowheight are 194,1220,2100,1892. Can't be same units?
var queue = new Queue<productionreportschema.production_builderrow>(_Orders.Count);
foreach (var row in _Orders)
queue.Enqueue(row);

PdfPTable table = null;
var page = 1;
for (ProductionReportSchema.Production_BuilderRow row = null; queue.Count > 0; )
{
row = queue.Peek();
if (table == null)
{
document.NewPage();
content.BeginText();
content.SetFontAndSize(courierbold, 12);
content.ShowTextAligned(left, "Production Report - Batch " + Batch, 36, 564, 0);
content.ShowTextAligned(centre, DateTime.Now.ToString(), 396, 564, 0);
content.ShowTextAligned(right, "Page " + page++, 756, 564, 0);
content.EndText();

table = new PdfPTable(10);
table.SetTotalWidth(new float[] { 24, 24, 50, 50, 50, 72, 72, 72, 24, 288 });
table.DefaultCell.HorizontalAlignment = centre;
table.AddCell(new Phrase("Done", GridBoldStyle));
table.AddCell(new Phrase("0-9", GridBoldStyle));
table.AddCell(new Phrase("B", GridBoldStyle));
table.AddCell(new Phrase("Order", GridBoldStyle));
table.AddCell(new Phrase("Line", GridBoldStyle));
table.AddCell(new Phrase("Item", GridBoldStyle));
table.AddCell(new Phrase("Colour", GridBoldStyle));
table.AddCell(new Phrase("Icon", GridBoldStyle));
table.AddCell(new Phrase("Qty", GridBoldStyle));
table.DefaultCell.HorizontalAlignment = left;
table.DefaultCell.VerticalAlignment = top;
table.AddCell(new Phrase("Name", GridBoldStyle));
table.CompleteRow();
}

table.DefaultCell.PaddingBottom = 0;
table.DefaultCell.Border = Rectangle.NO_BORDER;
table.DefaultCell.BorderWidthTop = 0.25f;
table.DefaultCell.HorizontalAlignment = centre;
var box = new PdfPCell(table.DefaultCell);
box.AddElement(row.Quantity == 1 ? checkbox : doublecheckbox);
table.AddCell(box); // done
table.AddCell(new Phrase(row.Priority.ToString(), GridStyle)); // priority
table.AddCell(new Phrase("B" + row.id, GridStyle)); // b#
table.AddCell(new Phrase("O" + row.OrderNo, GridStyle)); // order no
table.AddCell(new Phrase("L" + row.ODid, GridStyle)); // line#
table.AddCell(new Phrase(row.ItemNo, GridStyle)); // item
if (row.IsColourNull())
table.AddCell(string.Empty);
 
Share this answer
 
Comments
Richard Deeming 5-Mar-15 6:58am    
This question is nearly four years old!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900