Question

I'm creating a single pdf file that I'd like to link to other files in the same directory as the pdf.

ie.

MyFolder
        |
        |-main.pdf
        |-myotherpdf.pdf
        |-myotherotherpdf.pdf

I'd like the main.pdf to have links that would cause the default program on the pdf to open the other pdfs.

As I am generating these file on a server and then providing them in a download to the client I cannot use absolute links as these would not exist on the client pc.

So firstly do pdf files actually support relative file links like this, I haven't found much that says they do either way.

Additionally to generate my pdf I'm using abcpdf and providing it html to convert to pdf.

To try and generate the correct out the correct urls in html I have tried the following

<a href='test.pdf'>test pdf link to local file</a>
<a href='#test.pdf'>test pdf link to local file</a>
<a href='/test.pdf'>test pdf link to local file</a>
<a href='file:///test.pdf'>test pdf link to local file</a>
<a href='file://test.pdf'>test pdf link to local file</a>

Most of them either direct to me a point where the pdf document was generated from (temporary file path) or they link hovering shows "file:///test.pdf" in acrobat but clicking it causes a warning dialog to popup asking to allow/deny, upon clicking allow it opens up in firefox with the url "file:///test.pdf" which wouldn't resolve to anything.

Any ideas on how to get this working or if this kind of linking is even possible in pdfs?

Was it helpful?

Solution 2

So I got it working in the end thanks to @Frank Rem and some help from the abcpdf guys

Code is as follows

    foreach (var page in Enumerable.Range(0, doc.PageCount))
    {
        doc.PageNumber = page;

        var annotEnd = doc.GetInfoInt(doc.Page, "Annot Count");

        for (var i = 0; i <= annotEnd; ++i)
        {
            var annotId = doc.GetInfoInt(doc.Page, "Annot " + (i + 1));

            if (annotId > 0)
            {
                var linkText = doc.GetInfo(annotId, "/A*/URI*:Text");

                if (!string.IsNullOrWhiteSpace(linkText))
                {
                    var annotationUri = new Uri(linkText);

                    if (annotationUri.IsFile)
                    {
                        // Note abcpdf temp path can be changed in registry so if this changes
                        // will need to rewrite this to look at the registry
                        // http://www.websupergoo.com/helppdfnet/source/3-concepts/d-registrykeys.htm
                        var abcPdfTempPath = Path.GetTempPath() + @"AbcPdf\";

                        var relativePath = annotationUri.LocalPath.ToLower().Replace(abcPdfTempPath.ToLower(), string.Empty);

                        // Only consider files that are not directly in the temp path to be valid files
                        // This is because abcpdf will render the document as html to the temp path
                        // with a temporary file called something like {GUID}.html
                        // so it would be difficult to tell which files are the document
                        // and which are actual file links when trying to do the processing afterwards
                        // if this becomes and issue this could be swapped out and do a regex on {GUID}.html
                        // then the only restriction would be that referenced documents cannot be {GUID}.html
                        if (relativePath.Contains("\\"))
                        {
                            doc.SetInfo(annotId, "/A*/S:Name", "Launch");
                            doc.SetInfo(annotId, "/A*/URI:Del", "");
                            doc.SetInfo(annotId, "/A*/F:Text", relativePath);
                            doc.SetInfo(annotId, "/A*/NewWindow:Bool", "true");
                        }
                    }
                }
            }
        }
    }

This will allow each link to be opened in the viewer that is associated with it on the pc.

OTHER TIPS

I can only answer your question: does PDF files actually support relative file links like this?

Yes, it does. I created a little test with a main.pdf that has two links to two other PDF documents in the same folder. I created the links manually with Acrobat and associated a launch action with the link annotation. See the internal structure here:

enter image description here

Here is the zip with the main plus two secondary PDFs. Note that you can copy them anywhere and the relative links remain valid. https://www.dropbox.com/s/021tvynkuvr63lv/main.zip

I am not sure how you would accomplish this with abcpdf, especially since you are converting from HTML which probably limits the PDF features available.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top