Li Yang
Li Yang

Reputation: 11

How to add a PDF form field (or a text) and link in the page bottom of a page of an existing PDF document using iTextSharp?

I have an existing PDF document named as aa.pdf. This PDF document has 3 pages. I'd like to add a PDF form field (or a text) at the page bottom of the first page in aa.pdf using iTextSharp.

Meanwhile, I also hope that the PDF form field added (or the text added) can link into another page of aa.pdf. For example, after I click the PDF form field (or the text) located in the first page of aa.pdf,this PDF document skips into the second page.

How can I realize the aboved functionalities using iTextSharp?

Thanks.

Upvotes: 1

Views: 3231

Answers (1)

Chris Haas
Chris Haas

Reputation: 55427

To create links within a PDF you use a PdfAction which can be set on a Chunk which can optionally be added to a Paragraph. There are several different types of actions that you can choose from, the two that you are probably interested in are the NEXTPAGE action and/or the GotoLocalPage action. The first item does what it says and goes to the next page. This one is nice because you don't have to worry about figuring out what page number you are on. The second item allows you to specify the specific page number to go to. In its simplest form you can do:

Chunk ch = new Chunk("Go to next page").SetAction(new PdfAction(PdfAction.NEXTPAGE));

This creates a Chunk that you can add in whatever way you want. When working with an existing PDF there's several different ways to add text to a page. One way it to use a ColumnText object which has a method called SetSimpleColumn that allows you to define a simple rectangle that you can add elements to.

Lastly, PDF readers don't automatically treat links differently within a PDF except to give a different cursor when hovering. More specifically, unlike a webpage where hyperlinks are turned a different color, PDFs don't change the color of links unless you tell them to, so this should be kept in mind when creating them. Also, when modifying a PDF you generally never want to overwrite the existing PDF during the process because that would be writing to something that your reading from. Sometimes it works, more often then not it breaks, sometimes subtly. Instead, write to a second file and when you are completely done, erase the first file and rename the second file.

The code below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.2.0. The first part of the code creates a sample PDF called "aa.pdf" on the desktop. If you already have that file you can comment this section out but its in here so others can reproduce this example. The second part creates a new file called "bb.pdf" based on "aa.pdf". It adds two text links to the bottom of the first page. The first link advances the PDF to just the next page while the second link advances the PDF to a specific page number. See the comments in the code for specific implementation details.

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

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

        private void Form1_Load(object sender, EventArgs e) {
            //Files that we'll be working with
            string inputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "aa.pdf");
            string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "bb.pdf");

            //Create a standard PDF to test with, nothing special here
            using (FileStream fs = new FileStream(inputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
                using (Document doc = new Document(PageSize.LETTER)) {
                    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
                        doc.Open();

                        //Create 10 pages with labels on each page
                        for (int i = 1; i <= 10; i++) {
                            doc.NewPage();
                            doc.Add(new Paragraph(String.Format("This is page {0}", i)));
                        }

                        doc.Close();
                    }
                }
            }

            //For the OP, this is where you would start


            //Declare some variables to be used later
            ColumnText ct;
            Chunk c;

            //Bind a reader to the input file
            PdfReader reader = new PdfReader(inputFile);
            //PDFs don't automatically make hyperlinks a special color so we're specifically creating a blue font to use here
            iTextSharp.text.Font BlueFont = FontFactory.GetFont("Arial", 12, iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.BLUE);

            //Create our new file
            using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
                //Bind a stamper to our reader and output file
                using (PdfStamper stamper = new PdfStamper(reader, fs)) {

                    Chunk ch = new Chunk("Go to next page").SetAction(new PdfAction(PdfAction.NEXTPAGE));

                    //Get the "over" content for page 1
                    PdfContentByte cb = stamper.GetOverContent(1);

                    //This example adds a link that goes to the next page
                    //Create a ColumnText object
                    ct = new ColumnText(cb);
                    //Set the rectangle to write to
                    ct.SetSimpleColumn(0, 0, 200, 20);
                    //Add some text and make it blue so that it looks like a hyperlink
                    c = new Chunk("Go to next page", BlueFont);
                    //Set the action to go to the next page
                    c.SetAction(new PdfAction(PdfAction.NEXTPAGE));
                    //Add the chunk to the ColumnText
                    ct.AddElement(c);
                    //Tell the system to process the above commands
                    ct.Go();

                    //This example add a link that goes to a specific page number
                    //Create a ColumnText object
                    ct = new ColumnText(cb);
                    //Set the rectangle to write to
                    ct.SetSimpleColumn(200, 0, 400, 20);
                    //Add some text and make it blue so that it looks like a hyperlink
                    c = new Chunk("Go to page 3", BlueFont);
                    //Set the action to go to a specific page number. This option is a little more complex, you also have to specify how you want to "fit" the document
                    c.SetAction(PdfAction.GotoLocalPage(3, new PdfDestination(PdfDestination.FIT), stamper.Writer));
                    //Add the chunk to the ColumnText
                    ct.AddElement(c);
                    //Tell the system to process the above commands
                    ct.Go();
                }
            }

            this.Close();
        }
    }
}

Upvotes: 2

Related Questions