Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tables with rounded corners

Tags:

itextsharp

I was wondering what would be the best approach for creating tables in a pdf that have rounded corners using the iTextSharp 5.x+ library.

like image 688
Rick Make Avatar asked Mar 31 '10 23:03

Rick Make


2 Answers

If you have iTextSharp source code, add the following to PdfContentByte class:

/// <summary>
        /// Enumuration for defining corners you want rounded.
        /// </summary>
        [Flags()]
        public enum Corners {None = 0,All=15,Top=3,Bottom=12, TopLeft = 1, TopRight=2, BottomLeft=4, BottomRight=8};

        /// <summary>
        /// Adds a round rectangle to the current path, with rounded conrners as specified by roundCorners.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <param name="r"></param>
        /// <param name="roundCorners"></param>
        public void RoundRectangle(float x, float y, float w, float h, float r,Corners roundCorners)
        {
            if (w < 0)
            {
                x += w;
                w = -w;
            }
            if (h < 0)
            {
                y += h;
                h = -h;
            }
            if (r < 0)
                r = -r;
            float b = 0.4477f;
            if((roundCorners & Corners.BottomLeft) == Corners.BottomLeft)
                MoveTo(x + r, y);
            else
                MoveTo(x, y);

            if ((roundCorners & Corners.BottomRight) == Corners.BottomRight)
            {
                LineTo(x + w - r, y);
                CurveTo(x + w - r * b, y, x + w, y + r * b, x + w, y + r);
            }
            else
                LineTo(x + w, y);

            if ((roundCorners & Corners.TopRight ) == Corners.TopRight)
            {
                LineTo(x + w, y + h - r);
                CurveTo(x + w, y + h - r * b, x + w - r * b, y + h, x + w - r, y + h);
            }
            else
                LineTo(x + w, y + h);

            if ((roundCorners & Corners.TopLeft)  == Corners.TopLeft)
            {
                LineTo(x + r, y + h);
                CurveTo(x + r * b, y + h, x, y + h - r * b, x, y + h - r);
            }
            else
                LineTo(x , y + h);

            if ((roundCorners & Corners.BottomLeft) == Corners.BottomLeft)
            {
                LineTo(x, y + r);
                CurveTo(x, y + r * b, x + r * b, y, x + r, y);
            }else
                LineTo(x, y);
        }        

Next step is to implment IPdfPCellEvent interface:

public class myCellEvent : IPdfPCellEvent
    {
        #region members
        PdfContentByte.Corners _roundedCorners;
        float _roundness;
        #endregion

        #region ctor
        public myCellEvent()
            :this( PdfContentByte.Corners.All,2f)
        {

        }

        public myCellEvent(PdfContentByte.Corners roundedCorners)
            : this(roundedCorners, 2f)
        {

        }

        public myCellEvent(PdfContentByte.Corners roundedCorners,float roundness)
        {
            _roundedCorners = roundedCorners;
            _roundness = roundness;

        } 
        #endregion

        #region IPdfPCellEvent Members
        public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
        {
            PdfContentByte cb = canvases[PdfPTable.LINECANVAS];
            cb.RoundRectangle(position.Left, position.Bottom, position.Right - position.Left, position.Top - position.Bottom, this._roundness, this._roundedCorners);
            cb.SetColorStroke(new BaseColor(System.Drawing.Color.Black));
            cb.SetColorFill(new BaseColor(System.Drawing.Color.Beige));            
            cb.FillStroke();
            cb.Stroke();
        }
        #endregion
    }

Then you round what ever corners you want to produce the rounded table of choice:

PdfPTable table = new PdfPTable(1);


                PdfPCell cell = new PdfPCell(new Phrase(10, atext, f2));
                cell.Border = 0;
                cell.Padding = 5f;
                cell.CellEvent = new myCellEvent(PdfContentByte.Corners.Top,2f);
                table.AddCell(cell);

If you like the answer ... give it a vote :)

like image 163
MK. Avatar answered Oct 01 '22 03:10

MK.


There's no way to create an iTextSharp PdfPTable with rounded corners but what you could do is draw a table border with rounded corners using the PdfContentByte.RoundRectangle() method.

Here's a snippet that demonstrates this:

Document doc = new Document();
using (FileStream fs = new FileStream("RoundRectangle Demo.pdf", FileMode.Create)) {
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
    doc.Open();
    PdfContentByte cb = writer.DirectContent;

    // Bottom left coordinates x & y, followed by width, height and radius of corners.
    cb.RoundRectangle(100f, 500f, 200f, 200f, 2f);
    cb.Stroke();

    doc.Close();
}

This snippet is a condensed version of code I found in the article iTextSharp - Drawing shapes and Graphics on www.mikesdotnetting.com. You'll want to take a close look at his other articles if you haven't already.

like image 45
Jay Riggs Avatar answered Oct 01 '22 05:10

Jay Riggs