Vadym Shulyk
Vadym Shulyk

Reputation: 51

Set cell height in PDF table created with itextsharp

I used a following code to create a table in my itextsharp PDF document:

foreach (var subComp in competency.SubCompetensies)
{
    cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
    cell.Padding = 5;
    cell.Rowspan = 2;

    table.AddCell(cell);

    cell = new PdfPCell(new Phrase(0, subComp.Name, _nfSubComp));
    cell.Colspan = 10;
    cell.Padding = 5;
    table.AddCell(cell);

    cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
    cell.Padding = 5;
    cell.Rowspan = 2;

    table.AddCell(cell);

    for (int i = 1; i < 11; i++)
    {
        cell = new PdfPCell(new Phrase(0, i.ToString(), _nfScale));
        cell.FixedHeight = 15f;
        cell.Padding = 3;
        cell.PaddingLeft = 5;
        table.AddCell(cell);
    }
}

And here is the result:

PDF_Table

As you can see height of cells with numbers is different in every row. It seems that cell.FixedHeight property is ignored.

Is there any way to set fixed height of these cells?

Upvotes: 2

Views: 17466

Answers (1)

Vadym Shulyk
Vadym Shulyk

Reputation: 51

Well, I found a solution. As for me, it seems little pervert, but my deadline doesn't care about how exquisite my code is.

May be somene will find it useful.

Why FixedHeight is ignored?

Because the cells with the numbers drawn last they consume all the free space in a row.

Possible solutions

I can see only two ways:

  • Obviously, change the order of cells in a row
  • Render central part of the row by myself

I desided to choose the second way. Instead of creating therteen cells with rowspans/colspans and adding them to one row, I add only three cells:

 cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
                            cell.MinimumHeight = 50;
                            cell.Padding = 5;
                            cell.BorderColor = BaseColor.WHITE;
                            cell.BackgroundColor = new BaseColor(233, 240, 242);
                            table.AddCell(cell);

                            cell = new PdfPCell();
                            cell.CellEvent = new CellEvents(subComp);
                            cell.BorderColor = BaseColor.WHITE;
                            table.AddCell(cell);

                            cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
                            cell.Padding = 5;
                            cell.BorderColor = BaseColor.WHITE;
                            cell.BackgroundColor = new BaseColor(233, 240, 242);
                            table.AddCell(cell);

I add custom cell event to the second sell. It is fired after the cell height is set and before layout rendering. Here is the code of event handler:

 private class CellEvents : IPdfPCellEvent
{
    public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
    {

        int scoreCellHeight = 20;

        var pdfContentByte = canvases[0];
        pdfContentByte.SaveState();

        pdfContentByte.Rectangle(pos.Left, pos.Bottom + scoreCellHeight, pos.Width, pos.Height - scoreCellHeight);
        pdfContentByte.SetColorFill(new BaseColor(233, 240, 242));
        pdfContentByte.Fill();


        ColumnText ct = new ColumnText(pdfContentByte);
        ct.SetSimpleColumn(new Phrase(_model.Name, _nfSubComp), pos.Left, pos.Bottom + 20, pos.Left + pos.Width, pos.Bottom + pos.Height - 5, 10, Element.ALIGN_CENTER);
        ct.Go();

        float scaleWidth = pos.Width / 10;

        for (int i = 1; i < 11; i++)
        {
            float scaleLeft = pos.Left + (i - 1) * pos.Width / 10;

            pdfContentByte.Rectangle(scaleLeft, pos.Bottom, scaleWidth, scoreCellHeight);

            pdfContentByte.SetColorFill(i % 2 == 1
                ? new BaseColor(Color.LightBlue)
                : new BaseColor(233, 240, 242));
            pdfContentByte.Fill();


            ct.SetSimpleColumn(new Phrase(i.ToString(), _nfScale), scaleLeft, pos.Bottom,
                    scaleLeft + scaleWidth, pos.Bottom + 7, 0, Element.ALIGN_CENTER);
            ct.Go();
        }
        canvases[0].RestoreState();
    }
}

I've skipped some details like class constructor and the code, that draws marker (red figures on the screenshot).

Result:

PDF_result

I guess, this workaround is not optimal. But I had to draw a red marker, so I had to handle cell render event, anyway.

Hope, someone can show correct solution.

Upvotes: 3

Related Questions