Click here to Skip to main content
15,886,806 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Using the code below (also posted at http://stackoverflow.com/questions/38568690/how-to-insert-a-itextsharp-text-rectangle-rectangle-at-an-absolute-position),
C#
iTextSharp.text.Rectangle rectangle = new Rectangle(10, 10, 150, 15, 0);  
   // (lower-left-x, lower-left-y, upper-right-x (llx + width), upper-right-y (lly + height), rotation angle 
rectangle.BorderColor = BaseColor.WHITE;
rectangle.BackgroundColor = BaseColor.LIGHT_GRAY;
overContent.Rectangle(rectangle);
PdfAnnotation annotation = PdfAnnotation.CreateLink(
   stamper.Writer, rectangle, PdfAnnotation.HIGHLIGHT_INVERT,
   new PdfAction("http://itextpdf.com/") );            
stamper.AddAnnotation(annotation, 1);

I can create a hyperlink in the generated PDF. However, the Hyperlink rectangle is ALWAYS at the bottom-left of the generated PDF no matter how I change the x & y values in the Rectangle arguments (int x, int y, int width, int height). The annotation object does not have a method for setting its absolute position. If you have the experience on using iTextSharp, and particularly have the knowledge on the creation of hyperlink in the PDF, could you share your knowledge? Thanks.
// ********
This is the update of my Question
I tried another piece of code as below:
C#
using (System.IO.FileStream fs = new FileStream(Server.MapPath("pdf") + "\\" + "PDF with graphics and images.pdf", FileMode.Create)) {
   Document document = new Document(PageSize.A4, 25, 25, 30, 30);
   PdfWriter writer = PdfWriter.GetInstance(document, fs);
   Font link = FontFactory.GetFont("Arial", 12, Font.UNDERLINE, BaseColor.BLACK);  
   iTextSharp.text.Anchor anchor = new Anchor("www.mikesdotnetting.com", link);
   anchor.Reference = "http://www.mikesdotnetting.com";
   document.Add(anchor);

This hyperlink is also added but its position is on the top-left of the page. The iTextSharp.text.Anchor does bot have the setAbsolutePosition method. Is there a way to set the anchor at a desired position? Thanks.

What I have tried:

How to insert a iTextSharp.text.Rectangle rectangle at an absolute position?
Posted
Updated 14-May-18 2:21am
v2

I dont have experience with annotations - but often I need to position something absolutely on a page and I use a 'fake' table. If you can add your annotation to a 'cell', and I think you can, try this

PdfContentByte cb = writer.DirectContent;
PdfPTable table = new PdfPTable(1);
table.TotalWidth = 400f;
table.AddCell(//Annotation Details Here);
table.WriteSelectedRows(0, -1, 200, 50, cb);


You can set the table borders to whatever you wish, I make them invisible


Ok, this is 'the base' of my process :-

C#
PdfContentByte cb;

// Create PDF Reader For Input PDF
PdfReader reader = new PdfReader(//Source PDF File Name);

// Create Output PDF 
using (System.IO.FileStream fs = new System.IO.FileStream(//Target PDF Output File Name, System.IO.FileMode.Create))
{
    // Create PDF Stamper
    PdfStamper pdfStamper = new (PdfStamper, fs);

    // Get The Content Bytes For Page 1 
    cb = pdfStamper.GetOverContent(1);

    // Not Sure If this is needed 
    cb.BeginText();

    // Create a table and set a width

    PdfPTable table = new PdfPTable(1);
    table.TotalWidth = 400f;
    
    // Option 1 or Option 2 Here - I usually use 'builder' procedures for Tables/Paragraphs/Cells

    // Write the table at an absolute position 
    table.WriteSelectedRows(0, -1, 200, 50, cb);

    // If We've needed to use BeginText() We need this 
    cb.EndText();

    pdfStamper.FormFlattening = true;
    // Close Stamper
    pdfStamper.Close();
}


Then either of these two options


C#
// Option 1 - Using Paragraph + Chunk Allows For Alignment 

// Create Chunk with anchor
var webAddress = new Chunk("CodeProject");
// Set The anchor
webAddress.SetAnchor("http://www.codeproject.com");
// Crate a paragraph to hold the chunk
var para = new Paragraph(webAddress);
// Add some alignment to the paragraph
para.Alignment = Element.ALIGN_CENTER;
// Create a cell
PdfPCell anchorCell = new PdfPCell();
// Add the paragraph to the cell
anchorCell.AddElement(para);
// Can set padding on cell :-)
anchorCell.Padding = 30f;
// Set the cell border off 
anchorCell.Border = Rectangle.NO_BORDER;
// Add the cell to the table
table.AddCell(anchorCell);
//


or

C#
// Option 2 - Use Chunk, less formatting control 

// Create Chunk with anchor
var webAddress = new Chunk("CodeProject");
// Set The anchor
webAddress.SetAnchor("http://www.codeproject.com");
// Create a cell
PdfPCell anchorCell = new PdfPCell();
// Add the webAddress (chunk) to the cell
anchorCell.AddElement(webAddress);
// Set the cell border off 
anchorCell.Border = Rectangle.NO_BORDER;
// Add the cell to the table
table.AddCell(anchorCell);
//


You'll need to set

//Source PDF File Name
//Target PDF Output File Name

To values for a PDF file in (I use this as an 'underlay') and a PDF file out

btw - this is typed up from handwritten notes, Im on my mac and cant get to my dev machine at the moment, so it may need a bit of editing here and there

You can copy Option 1 or 2 in here (or make a static procedure and pass in cb / ContentBytes

Quote:
// Option 1 or Option 2 Here - I usually use 'builder' procedures for Tables/Paragraphs/Cells


.. as it says, I usually have a set of 'builders' that allow me to assembly fonts, paragraphs from chunks, tables from cells etc


Complete working example (Create PDF From scratch)

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CPPDF001
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseFont bfTimesRoman = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);

            Font fTimesRomanItalic10 = new Font(bfTimesRoman, 10, Font.ITALIC, BaseColor.BLACK);

            String testPDFName = "CPPFF001.pdf";
            if (File.Exists(testPDFName))
            {
                File.Delete(testPDFName);
            }

            using (FileStream fs = new FileStream("CPPFF001.pdf", FileMode.Create))
            {
                Document doc = new Document(PageSize.A4, 25,25,30,30);
                PdfWriter writer = PdfWriter.GetInstance(doc, fs);

                doc.Open();
                PdfContentByte cb = writer.DirectContent;

                cb.BeginText();

                writeText(cb, "Garth Was Here !!!", 30, 718, bfTimesRoman, 14);

                // Note the implications of this wrt chunks in Try 1 and Try 2
                cb.SetFontAndSize(bfTimesRoman, 10);

                PdfPTable table = new PdfPTable(1);
                table.TotalWidth = 400f;

                // Try 1 : This works - NB Will Have a Rectangle Around it
                // Note that because we're using a chunk, its font/size is
                // dependand upon the statement :-
                //
                // cb.SetFontAndSize(bfTimesRoman, 10);
                //
                
                var chunk = new Chunk("CodeProject");
                chunk.SetAnchor("http://www.codeproject.com");
                chunk.SetUnderline(0.5f, -1.5f);

                PdfPCell cell = new PdfPCell();
                cell.AddElement(chunk);
                table.AddCell(cell);
                table.WriteSelectedRows(0, -1, 30, 646, cb);
                // Try 1 End


                // Try 2 : This also works - NB Will not have a Border/Rectangle Around it
                // Note that because we're using a chunk, its font/size is
                // dependand upon the statement :-
                //
                // cb.SetFontAndSize(bfTimesRoman, 10);
                //

                PdfPTable table1 = new PdfPTable(1);
                table1.TotalWidth = 100f;

                PdfPCell cell1 = new PdfPCell();
                cell1.AddElement(chunk);
                cell1.Border = Rectangle.NO_BORDER;

                table1.AddCell(cell1);
                table1.WriteSelectedRows(0, -1, 30, 574, cb);
                // Try 2 End

                // Try 3 : This also works 
                //   NB Will not have a Border/Rectangle Around it
                //      Will Be In Italic, No Underline

                PdfPTable table2 = new PdfPTable(1);
                table2.TotalWidth = 100f;

                PdfPCell cell2 = new PdfPCell();

                // Note the chunk formatting here :-)
                var chunk1 = new Chunk("CodeProject", fTimesRomanItalic10);
                chunk1.SetAnchor("http://www.codeproject.com");

                //var paragraph = new Paragraph(chunk1); 
                cell2.AddElement(chunk1);
                cell2.Border = Rectangle.NO_BORDER;

                table2.AddCell(cell2);
                table2.WriteSelectedRows(0, -1, 30, 502, cb);
                // Try 3 End

                cb.EndText();
                doc.Close();

            } // using

        } // Main

        static void writeText(PdfContentByte cb, string text, int x, int y, BaseFont font, int size)
        {
            cb.SetFontAndSize(font, size);
            cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, text, x, y, 0);
        }

        // Obviously you'd re-factor Try1-3 Into Code that looked like
        /*
           static Chunk CreateChunk(string text,
                                    string link,
                                    Font font,
                                    int fontSize)
           {
               // Create and return Chunk
           }

           static PDFPCell CreateCell(Chunk chunk,
                                    bool borderOrNot)
           {
               // Create and return Cell, using chunk
           }

           static Table CreateTable(PDFPcell cell,
                                    int rectangleSize)
           {
               // Create and return Table
           }

           static void AddAnnotation(PdfContentByte cb,
                                     string text,
                                     string link, 
                                     Font font,
                                     int fontSize,
                                     int positionX,
                                     int positionY,
                                     bool borderOrNot,
                                     int rectangleSize)
           {
                // Build Chunk using text, link, font, fontSize
                // Build Cell, Add Chunk To Cell And Turn Border Off if borderOrNot == true
                // Build Table, set width to rectangleSize
                // Write Table to cb, positionX, positionY
          
           }
        */

        }
    }
}


Complete working example (annotating existing PDF)

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CPPDF001
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseFont bfTimesRoman = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);

            Font fTimesRomanItalic10 = new Font(bfTimesRoman, 10, Font.ITALIC, BaseColor.BLACK);

            //
            // ** Part 1 - Create a PDF to Stamp/Annotate **
            //

            String testPDFName = "CPPDF001.pdf";
            if (File.Exists(testPDFName))
            {
                File.Delete(testPDFName);
            }

            // Create a simple PDF to use for Underlay
            using (FileStream fs = new FileStream(testPDFName, FileMode.Create))
            {
                Document doc = new Document(PageSize.A4, 25,25,30,30);
                PdfWriter writer = PdfWriter.GetInstance(doc, fs);

                doc.Open();
                PdfContentByte cb = writer.DirectContent;

                // Note the implications of this wrt chunks in Try 1 and Try 2
                cb.SetFontAndSize(bfTimesRoman, 10);

                cb.BeginText();

                writeText(cb, "CodeProject Is Neat !!!", 30, 718, bfTimesRoman, 14);

                cb.EndText();
                doc.Close();

            } // using - PDF Creation


            //
            // ** Part 2 - Use the PDF From Part 1 and Annotate it with a Hyperlink using PDFStamp process **
            //

            String testPDFNameStamped = "CPPDF001-Stamped.pdf";
            if (File.Exists(testPDFNameStamped))
            {
                File.Delete(testPDFNameStamped);
            }

            PdfReader reader = new PdfReader(testPDFName);

            using (System.IO.FileStream fs = new System.IO.FileStream(testPDFNameStamped, System.IO.FileMode.Create))
            {
                PdfStamper pdfStamper = new PdfStamper(reader, fs);

                // reader.NumberOfPages are indexed from 1 not 0
                // depending on how your PDF has been constructed you might need to use .GetUnderContent()
                PdfContentByte cb = pdfStamper.GetOverContent(1);

                cb.BeginText();

                PdfPTable table1 = new PdfPTable(1);
                table1.TotalWidth = 100f;

                PdfPCell cell1 = new PdfPCell();

                // Note the chunk formatting here :-)
                var chunk1 = new Chunk("CodeProject", fTimesRomanItalic10);
                chunk1.SetAnchor("http://www.codeproject.com");

               
                cell1.AddElement(chunk1);
                //cell1.Border = Rectangle.NO_BORDER;

                table1.AddCell(cell1);
                table1.WriteSelectedRows(0, -1, 30, 646, cb);

                cb.EndText();

                pdfStamper.FormFlattening = true;
                pdfStamper.Close();

            } // using - PDF Stamp

        } // Main

        static void writeText(PdfContentByte cb, string text, int x, int y, BaseFont font, int size)
        {
            cb.SetFontAndSize(font, size);
            cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, text, x, y, 0);
        }
    }
}
 
Share this answer
 
v4
Comments
s yu 4-Aug-16 12:39pm    
Tried but got compiling error at
table.AddCell(annotation);
where annotaion is an PdfAnnotation. Any new hint? Thanks.
Garth J Lancaster 4-Aug-16 19:19pm    
Any new Hint ? bit hard without seeing your code and details of the compilation error - cant read your mind nor see your screen from out here
s yu 8-Aug-16 13:42pm    
Garth: Thanks for your comment. I updated my Q w/ 2nd part which contains a new piece of code. Could you review it and see if you can provide your advisory? Thanks.
Garth J Lancaster 9-Aug-16 1:28am    
I dont know the default/anchoring policy ... so I doubt its going to work - the process I use is a bit (no, a lot more) involved, in that I have a professionally created PDF document and Im 'stamping' information over it and creating a new pdf .. I'll post the code tonight, I dont know if it'll work for you this way, it certainly lets me put tables with figures and/or graphics wherever on the page I want, plus I put text out as well
Garth J Lancaster 9-Aug-16 3:58am    
ok, have a look at what Ive provided - I hope its some use, its likely very different from what you need, and Ive typed it from notes (I cant use my prod code for another company, sorry)
PdfContentByte cb = pdfwrite.DirectContent;
              var Rectangular = new Rectangle(56, 621, 540,385);
              Rectangular.BorderWidthLeft = 0.1f;
              Rectangular.BorderWidthRight = 0.1f;
              Rectangular.BorderWidthTop = 0.1f;
              Rectangular.BorderWidthBottom = 0.1f;
              cb.Rectangle(Rectangular);
              cb.Stroke();
 
Share this answer
 
Comments
CHill60 14-May-18 8:26am    
Look at the Accepted Solution. The poster has put a lot of effort into explaining the code and conversing with the OP. The OP has confirmed that the solution worked both in writing and by officially accepting the answer a year ago. What makes you think that they will appreciate an uncommented code dump with no context?
It's good that you want to help, but please try to bring something new to threads and explain why your solution is better than any others posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900