Itextsharp gradient background

10,785

Solution 1

Yes, iText and iTextSharp support gradient colors. The PdfShading object has several static methods that create different types of PdfShading objects for you. The two that you are probably most interested in are SimpleAxial and SimpleRadial. There's three others named Type1, Type2 and Type3 that I haven't explored yet.

Once you have a PdfShading object you can create a PdfShadingPattern directly from it and once you have that you can create a ShadingColor from it. ShadingColor is ultimately derived from BaseColor so you should be able to use it wherever that's used. In your case you want to assign it to a BackgroundColor.

Below is a complete working WinForms app targeting iTextSharp 5.1.1.0 that shows created a table with two columns, each with their own gradient background colors.

NOTE: The (x,y) coordinates of the PdfShading static methods are document-level and not cell-level. What this means is that you might not be able to re-use PdfShading ojbects depending on the gradient's size. After this sample below I'll show you how to overcome this limitation using cell events.

using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Test file name
            string TestFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");

            //Standard iTextSharp setup
            using (FileStream fs = new FileStream(TestFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (Document doc = new Document(PageSize.LETTER))
                {
                    using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
                    {
                        //Open the document for writing
                        doc.Open();

                        //Create a shading object. The (x,y)'s appear to be document-level instead of cell-level so they need to be played with
                        PdfShading shading = PdfShading.SimpleAxial(w, 0, 700, 300, 700, BaseColor.BLUE, BaseColor.RED);

                        //Create a pattern from our shading object
                        PdfShadingPattern pattern = new PdfShadingPattern(shading);

                        //Create a color from our patter
                        ShadingColor color = new ShadingColor(pattern);

                        //Create a standard two column table
                        PdfPTable t = new PdfPTable(2);

                        //Add a text cell setting the background color through object initialization
                        t.AddCell(new PdfPCell(new Phrase("Hello")) { BackgroundColor = color });

                        //Add another cell with everything inline. Notice that the (x,y)'s have been updated
                        t.AddCell(new PdfPCell(new Phrase("World")) { BackgroundColor = new ShadingColor(new PdfShadingPattern(PdfShading.SimpleAxial(w, 400, 700, 600, 700, BaseColor.PINK, BaseColor.CYAN))) });



                        //Add the table to the document
                        doc.Add(t);

                        //Close the document
                        doc.Close();
                    }
                }
            }

            this.Close();
        }

    }
}

Example 2

As noted above, the method above uses document-level position which often isn't good enough. To overcome this you need to use cell-level positioning and to do that you need to use cell events because cell positions aren't known until the table itself is rendered. To use a cell event you need to create a new class that implements IPdfPCellEvent and handle the CellLayout method. Below is updated code that does all of this:

using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Test file name
            string TestFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");

            //Standard iTextSharp setup
            using (FileStream fs = new FileStream(TestFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (Document doc = new Document(PageSize.LETTER))
                {
                    using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
                    {
                        //Open the document for writing
                        doc.Open();

                        //Create a standard two column table
                        PdfPTable t = new PdfPTable(2);

                        //Create an instance of our custom cell event class, passing in our main writer which is needed by the PdfShading object
                        var CE = new GradientBackgroundEvent(w);

                        //Set the default cell's event to our handler
                        t.DefaultCell.CellEvent = CE;

                        //Add cells normally
                        t.AddCell("Hello");
                        t.AddCell("World");


                        //Add the table to the document
                        doc.Add(t);

                        //Close the document
                        doc.Close();
                    }
                }
            }

            this.Close();
        }

        public class GradientBackgroundEvent : IPdfPCellEvent
        {
            //Holds pointer to main PdfWriter object
            private PdfWriter w;

            //Constructor
            public GradientBackgroundEvent(PdfWriter w)
            {
                this.w = w;
            }

            public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
            {
                //Create a shading object with cell-specific coords
                PdfShading shading = PdfShading.SimpleAxial(w, position.Left, position.Bottom, position.Right, position.Top, BaseColor.BLUE, BaseColor.RED);

                //Create a pattern from our shading object
                PdfShadingPattern pattern = new PdfShadingPattern(shading);

                //Create a color from our patter
                ShadingColor color = new ShadingColor(pattern);

                //Get the background canvas. NOTE, If using an older version of iTextSharp (4.x) you might need to get the canvas in a different way
                PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS];

                //Set the background color of the given rectable to our shading pattern
                position.BackgroundColor = color;

                //Fill the rectangle
                cb.Rectangle(position);
            }
        }
    }
}

Solution 2

If anyone else is still interested I was looking to find out how to color the whole background with a gradient you can do it like this....

    PdfShading shading = PdfShading.simpleAxial(writer, 0, pageH, pageW, 0,
            BaseColor.WHITE, BaseColor.LIGHT_GRAY);
    PdfShadingPattern pattern = new PdfShadingPattern(shading);
    cb.setShadingFill(pattern);
    // cb.circle(500, 500, 500);
    cb.rectangle(0, 0, pageW, pageH);
    cb.fill();
Share:
10,785
Roggo
Author by

Roggo

Updated on June 05, 2022

Comments

  • Roggo
    Roggo almost 2 years

    Is there way to set gradient background to pdfcell or paragraph? Or do I have to use image?

  • Paddy
    Paddy almost 12 years
    Great answer. Fricking itext documentation should read like this.
  • Ben
    Ben over 11 years
    @ChirsHaas any chance you could help me fill a circle with a radial gradient starting in the centre? pretty please