Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoFit Table Column Widths using iTextSharp and C#

I've exported DataGridView data to PDF using iTextSharp. The column widths are all exactly the same, and some of the header column words are broken up incorrectly. What I'm trying to do is autofit the header columns widths to adjust to each header text length.

Here's my code :

 PdfPTable table = new PdfPTable(dgv.Columns.Count);
        for (int j = 0; j < dgv.Columns.Count; j++)
        {
            Font font = new Font(Font.FontFamily.COURIER, 14, Font.ITALIC);
            font.Color = BaseColor.BLUE;

            if (j == 0)
            {
                Phrase p1 = new Phrase(dgv.Columns[j].HeaderText, font);
                table.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.WidthPercentage = 100;
                table.AddCell(p1);
            }

            else
            {
                string header = dgv.Columns[j].HeaderText;
                header = Regex.Replace(dgv.Columns[j].HeaderText, "[A-Z]", " $0").Trim();
                Phrase p = new Phrase(header, font);
                table.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.WidthPercentage = 100;
                table.AddCell(p);
            }
        }
        table.HeaderRows = 1;

        for (int i = 0; i < dgv.Rows.Count; i++)
            for (int k = 0; k < dgv.Columns.Count; k++)
                if (dgv[k, i].Value != null)
                {
                    Phrase p = new Phrase(dgv[k, i].Value.ToString());
                    table.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER;
                    table.AddCell(p);
                }


        doc.Add(table);

And this is the PDF output:

enter image description here

like image 250
Kfir Avatar asked Mar 10 '23 15:03

Kfir


1 Answers

To auto-fit column sizes, you need to calculate the width of the header strings yourself, then set the table column widths.

First a simple helper method to get the column widths from an arbitrary collection of strings:

public float[] GetHeaderWidths(Font font, params string[] headers)
{ 
    var total = 0;
    var columns = headers.Length;
    var widths = new int[columns];
    for (var i = 0; i < columns; ++i)
    {
        var w = font.GetCalculatedBaseFont(true).GetWidth(headers[i]);
        total += w;
        widths[i] = w;
    }
    var result = new float[columns];
    for (var i = 0; i < columns; ++i) 
    {
        result[i] = (float)widths[i] / total * 100;
    }
    return result;
}

Then set the table column widths:

string[] headers = new string[]
{ 
    "Order Id", "Customer Id", "Customer Name", "Product Id",
    "Product Description", "Quantity", "Product Received"
};
Font font = new Font(Font.FontFamily.COURIER, 14, Font.ITALIC);
font.Color = BaseColor.BLUE;
var table = new PdfPTable(headers.Length) { WidthPercentage = 100 };
table.SetWidths(GetHeaderWidths(font, headers));

using (var stream = new MemoryStream())
{
    using (var document = new Document(PageSize.A4.Rotate()))
    {
        PdfWriter.GetInstance(document, stream);
        document.Open();
        for (int i = 0; i < headers.Length; ++i)
        {
            table.AddCell(new PdfPCell(new Phrase(headers[i], font)));
        }
        document.Add(table);
    }
    File.WriteAllBytes(OUT_FILE, stream.ToArray());
}

The output:

enter image description here

like image 144
kuujinbo Avatar answered Mar 12 '23 06:03

kuujinbo