Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Automating changing link to open an attachment

New Here ,
Apr 04, 2025 Apr 04, 2025

Hi,

 

We've got a PDF that needs distribution to customers, and we'd like to include a CSV file as an attachment and also update one link in the PDF to open the attachment (by default, this link in the PDF is a web link to an external version of the CSV file that lives in the same directory as the PDF).

 

As this PDF gets rebuilt often, I'd like to be able to make a one button action/command to attach the CSV file and then update the link to open the attached file instead of a web link to the external file.

 

Part one I have managed to do easily enough. However, I can't work out how I could achieve the following with an Action/Command in Acrobat:

 

1. Find the link text in the PDF (my.csv)

2. Automatically change the link action from "Open a web link: my.csv" to

Run a Javascript: 
/* Launch attached CSV file */
this.exportDataObject({cName: "my.csv", nLaunch: 2});

 

So, that little bit of JavaScript above does exactly what I want it to do, I just want to be able to click an Action/Command button and find the text and change the existing link to behave like in step two. It feels like I should be able to change the link behavior with JavaScript, but I am really struggling to work out how!

Any help, much appreciated.

TOPICS
JavaScript , PDF
235
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 04, 2025 Apr 04, 2025

You can override the link's action with a script. The problem is, you can't know what the original action was.

So if you want to convert all links in the file to this new action you can do it quite easily, but if you want to check first that they actually point to my.csv (and not to another file, or a web-page, etc.), then you will need an external tool to do it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 04, 2025 Apr 04, 2025

You can find all the links on a page with the "doc.getLinks()" function. Here's the reference entry (it includes an example):

https://opensource.adobe.com/dc-acrobat-sdk-docs/library/jsapiref/doc.html#getlinks

Each link object has a "setAction" command that sets the JavaScript action.

Finding the text under the link in order to verify the correct link is a more difficult issue. Once you have a link object, you can get it's rectangle. So it's a matter of searching the page words for any that are inside the link rectangle. 

Use the doc.getPageNthWordQuads() function to find the quads associated with each word on the page. Some geometric calculations will be necessary to determine which quad is under the  link rectangle. 

 

 

 

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 07, 2025 Apr 07, 2025

Thank you both. The link that @Thom Parker provided actually had almost the exact code I needed. I setup our authoring software to not include any kind of link, so it just outputs plain text, and this scripts finds the text and adds a square link around it. 

 

This works fine for something like "myfile", but ideally, I'd like the text in the PDF to look like "my_file.csv". However, if I set the script below to add a link to the text "my_file.csv" (ckWord == "my_file.csv") nothing happens. Based on what I read about the getPageNthWord function, maybe the function is breaking "my""_"file""." and "csv" into separate words, so won't find them. Any quick way to sort that issue? 

 

Also, there will literally only ever be onone instance of this text in the PDF, I've made a rather rudimentary break once it has found the string it is looking for, but I'm wondering if there is a more efficient way of doing it. Currently the script takes about 30 seconds to run when the strict is about half way through an 88 page PDF.

for (var p = 0; p < this.numPages; p++) {
    var numWords = this.getPageNumWords(p);
    var foundit = 0;

    for (var i = 0; i < numWords; i++) {
        var ckWord = this.getPageNthWord(p, i, true);

        if (ckWord == "portslist") {
            var q = this.getPageNthWordQuads(p, i);
            // Convert quads in default user space to rotated
            // User space used by Links.
            var m = (new Matrix2D).fromRotated(this, p);
            var mInv = m.invert();
            var r = mInv.transform(q);
            r = r.toString();
            r = r.split(",");
            var l = addLink(p, [r[4], r[5], r[2], r[3]]);
            l.borderColor = color.blue;
            l.borderWidth = 1;
            l.setAction("this.exportDataObject({cName: 'portslist.csv', nLaunch: 2})");
            foundit = 1;
            break; // Exit the inner loop
        }
    }

    if (foundit == 1) {
        break; // Exit the outer loop
    }
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2025 Apr 07, 2025
LATEST

The "getPageNthWord()" function returns a single word. In the Acrobat JS model a single word is any continous seqence of Alphnumeric characters.  The word can also includes a single trailing non-alphnumeric character, i.e., punctuation or white space.  So "my_file.csv" is actually two words. To catch this case the code would need to capture two words.  But it can get much more complicated. What if there are more then 2 words in an entry in the CSV file? What if the number of words per entry is arbitrary?  What if the puntuation and spacing between the CSV and document is different? What if there are differences in capitalization? 

One solution is to reduce the csv entry into an array of single lower case words with no punctuation. Then the search starts by looking for the first word in the array. Once found it then tries to match the following words in the array against the following words on the page. 

   

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines