Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a hyperlink into a PDF document

I'm currently extending our custom PDF writer to be able to write links to websites. However, I have a problem because I can't find anywhere how to place a link into the PDF.

This is, what prints a text:

BT
70 50 TD
/F1 12 Tf
(visit my website!) Tj
ET

What I need now is to wrap this into a hyperlink so the user gets redirected to my website, when clicking "visit my website!"

Any idea how to do so? I can't use a tool or so - I need to know how to write the right PDF commands to the file, since a lot of documents are generated dynamically using C#. Currently I'm using iTextSharp - but I couldn't find any functionality to write a hyperlink, so I decided to add this functionality.

like image 257
NeoKenshinX Avatar asked Mar 21 '23 23:03

NeoKenshinX


2 Answers

Here's how the spec side of things: Links are created by having Link Annotations placed on the page. A link annotation is represented by either the Rect key or by a set of quadrilaterals. Let's assume that you're working with rectangles. In order to place the link, you'll need a dictionary like this at a minimum:

<< /Type /Annot /Subtype /Link /Rect [ x1 y1 x2 y2 ] >>

(x1, y1) and (x2, y2) describe the corners of the rectangle where the link's active area lives.

To work with this, this should be an indirect object in the PDF and referenced from your page's Annots array.

If you can create this, you'll get a link on the page that goes nowhere.

To get the link to go somewhere you'll need either a /Dest or an /A entry in the link annot (but not both). /Dest is an older artifact for page-level navigation - you won't use this. Instead, use the /A entry which is an action dictionary. So if you wanted to navigate to the url http://www.google.com, you would make your annotation look like this:

<< /Type /Annot /Subtype /Link /Rect [ x1 y1 x2 y2 ]
   /A << /Type /Action /S /URI /URI (http://www.google.com) >>
>>

I can't help you specifically with how to do this in iTextSharp. I don't particularly like the model or abstraction that they use. I write a PDF toolkit for Atalasoft and I'll show you how I would do that in my own toolkit. Again, I'm making no effort to conceal that this is a commercial product and it's what I do for a living. I just want you to see that there are other options available.

// make a document, add a font, get its metrics
PdfGeneratedDocument doc = new PdfGeneratedDocument();
string fontResource = doc.Resources.Fonts.AddFromFontName("Times New Roman");
PdfFontMetrics mets = doc.Resources.Fonts.Get(fontResource).Metrics;

// make a page, place a line of text
PdfGeneratedPage page = doc.Pages.AddPage(PdfDefaultPages.Letter);
PdfTextLine line = new PdfTextLine(fontResource, 12.0, "Visit my web site.",
                        new PdfPoint(72, 400));
page.DrawingList.Add(line);

// get the bounds of the text we place, make an annotation
PdfBounds bounds = mets.GetTextBounds(12.0, "Visit my web site.");
bounds = new PdfBounds(72, 400, bounds.Width, bounds.Height);
LinkAnnotation annot = new LinkAnnotation(bounds, new PdfURIAction(new URI("my url")));
page.Annotations.Add(annot);

// save the content
doc.Save("finaldoc.pdf");

The only thing that is "tricky" is that there is a disassociation between what content is on the page and the link annotation - but this is because this is how Acrobat models links. If you were modifying an existing document, you would construct a PdfGeneratedDocument from the existing file/stream, add the annotation and then save.

like image 129
plinth Avatar answered Mar 24 '23 12:03

plinth


Currently I'm using iTextSharp - but I couldn't find any functionality to write a hyperlink.

Have a look at the iText in Action, 2nd Edition Webified iTextSharp Examples MovieLinks2.cs or LinkActions.cs:

// create an external link
Chunk imdb = new Chunk("Internet Movie Database", FilmFonts.ITALIC);
imdb.SetAnchor(new Uri("http://www.imdb.com/"));
p = new Paragraph("Click on a country, and you'll get a list of movies, containing links to the ");
p.Add(imdb);
p.Add(".");
document.Add(p);

Thus, it really is simple to add links using iTextSharp.

If you still want to do that manually, have a look at the PDF specification. Section 12.5.6.5 explains Link Annotations, and section 12.6.4.7 shows the URI Actions to use in that link annotation.

like image 20
mkl Avatar answered Mar 24 '23 12:03

mkl