Skip to main content
Participating Frequently
October 1, 2020
Answered

Javascript watermark which uses list of inputted names to batch watermark a file

  • October 1, 2020
  • 1 reply
  • 4974 views

Hi there, and thanks in advance for any advice.

 

I've written a simple script to ask the user for a name, watermark files with this input, and then save the file with the same input added to the filename.

 

As part of my job, it would be even more useful if I could input a list of names and batch watermark them at the same time.

 

My script so far is below. I have python and html/css experience, so I know vaguely how to do this: set the WaterName variable from the top of the list, run the watermark and saveAs commnads, then go back to line 2 of the list and repeat until there are no more names left.

 

But I'm new to Javascript in Acrobat and would really appreciate any tips.

 

Thanks,

Ben

 

// Ask user for Name

var dialogTitle = "Enter Name";
var WaterName = app.response("Watermark Text",
dialogTitle);

// Add watermark
event.target.addWatermarkFromText({
	cText: WaterName,
	nTextAlign:app.constants.align.center,
	cFont: "Arial",
	nScale: -1,
	nRotation: 45,
	nOpacity: 0.06
});


// Build File Name addition from Name
var cExt = (" - " + WaterName + ".pdf");

//Add the extension to the end of the file name 
var cDstName = event.target.documentFileName.replace(/\.pdf$/,cExt);

// Save the file
event.target.saveAs(cDstName);

 

This topic has been closed for replies.
Correct answer Thom Parker

Thanks Thom. That makes total sense. I have rejigged as you describe, but unfortunately there's still something not right - I am sure I've made a stupid mistake. My code is below. As it is, it is saving copies like this:

 

- "File1 - First name.pdf" - with no watermark

- "File2 - Second name.pdf" - with a watermark of the first name (!!?)

 

So it appears there's something wrong with the opening and closing of the newly saved copies.

Thanks

 

// Prompt user for the list
var WaterNamePlu = app.response({ cQuestion: "Enter Watermark Text", cTitle: "Watermark text"});
//Parse list
var aNames = WaterNamePlu.split(",");

//Loop the list till complete
for(var i=0;i<aNames.length;i++)
{
    
    WaterName = aNames[i];
    
    // Build File Name addition from Name
    var cExt = (" - " + WaterName + ".pdf");
    //Add the extension to the end of the file name and create save path
    var cDstName = this.documentFileName.replace(/\.pdf$/,cExt);
    var cDstPath = "/Users/Ben/Desktop/" + cDstName; 
    // Save the renamed copy
    this.saveAs({cPath:cDstPath, bCopy:true});
    
    app.openDoc(cDstPath);
    
    event.target.addWatermarkFromText({
        cText: WaterName,
        nTextAlign:app.constants.align.center,
        cFont: "Arial",
        nScale: -1,
        nRotation: 45,
        nOpacity: 0.06
    });
    
    // Save and close the renamed copy
    app.execMenuItem("Save");
    this.closeDoc();
    
}

 


Very Very Close!

Both "event.target" and "this" always refers to the document being operated on by the batch process (i.e. Action), which is the original.  The script needs to work on the document opened with "app.openDoc".

Also, it should be opening it as "hidden"

 

var oDoc = app.openDoc({cPath:cDstPath,bHidden:true});

oDoc.addWatermarkFormText(...);

oDoc.saveAs(cDstPath);

oDoc.closeDoc();

1 reply

Thom Parker
Community Expert
October 1, 2020

You're script looks great. So is the list of names used to watermark the same file multiple times? Or is each name to be used on a different file? 

Here's an article on string processing. 

https://acrobatusers.com/tutorials/splitting-and-rebuilding-strings/

 

Let's say that the list of names is applied to the same file. And lets say the names are entered as a comma separated list.

Then you'd write a loop like this

 

var WaterNames = app.response("Watermark Text",
dialogTitle);
var aNames = WaterNames.split(",");
for(var i=0;i<aNames.length;i++)
{
    WaterName = aNames[i];
  ... Same code as before ...
}

 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
BenH42Author
Participating Frequently
October 5, 2020

Thanks so much Thom. The original script was based on your own previous responses in this forum!

 

I've tried the script you suggest, and it works in prinicple, but there's one bug:

My script currently runs in Action Wizard as an Execute Javascript action, and runs its action on the file currently open. The result is that with this new String loop, the script gets the names, watermarks the first script, then performs the same watermarking action on the file it has just watermarked already. So the outputted files are cummulatively watermarked with more and more names from the list. How can I tell Adobe to SaveAs the file it has watermarked, then return to the original file it began with?

 

In answer to your question: yes, it's a list of names used to watermark a single file, saving a copy of the file for each recipient watermarked with their name. In an ideal world, the script would be able to process multiple files for multiple names. That is, I have two names (BEN, HARRY), and I have two files selected in Action Wizard by the user (file1.pdf, file2.pdf), and the script pumps out:

file1 - BEN.pdf

file1 - HARRY.pdf

file2 - BEN.pdf

file2 - HARRY.pdf

Using the current script, if I run the Action with more than one file selected, it just prompts me at each file for a new set of names. If it's possible to have Adobe do this on multiple files all at once, that would be great.

 

Finally, we tend to recieve names in lists delimited by a line break. Is there a way to tell Adobe to delimit by line break? If not, should I process the original list and replace line breaks with something Javascript can delimit?

BenH42Author
Participating Frequently
October 21, 2020

For the parameter you've described you'll need to use a Text Annotation. Annotations can be arbitrarily rotated Fields can only be rotated at 90 degree increments.  

 

A good way to figure out exactly what Annotation parameters you'll need is to place one manually on a PDF Page, just like you want it. Then select the annot, then run this code in the console window. 

 

for(var nm in selectedAnnots[0]){

   if((typeof(selectedAnnots[0][nm]) != "function") && (typeof(selectedAnnots[0][nm]) != "object"))

       console.println(nm + " = " + selectedAnnots[0][nm]);

}

 

This will print out all of the annotations properties that are settable, except for the positioning rectangle. 

 

 

 


Hi Thom

I've tried all different solutions you have suggested and have found them really hard to make work - the text annotations simply don't look right on the page for our purposes - it's too obvious that they're not watermarks. I have ended up trying to return to the original plan - establish the open file, ask for a list of names, then loop the watermark function by opening and closing the right file. I know it's not efficient, but the lists are never more than 10 names long, so it seems like the way to go.

 

The script I'm trying is below, and it's still not working. The result is still a set of docs with the list of names watermarked on top of one another, and an alert message 'The current action is not yet complete. Do you want to exit this action?'.

 

I think the problem is that the loop is still looping the watermark function on an already watermarked document, and then it is not closing the document until the script is complete. And it seems like closeDoc in this context breaks the script out of the action?

 

Am I doing something wrong in the 'for' function? Is there a way to close and reopen the document within the looping 'for' section?

 

Many thanks in advance

 

//Establish Open File
var CurPDF = this.path;

// Prompt user for the list
var WaterNamePlu = app.response({ cQuestion: "Enter Watermark Text", cTitle: "Watermark text"});
//Parse list
var aNames = WaterNamePlu.split(",");

for(var i=0;i<aNames.length;i++)
{
    
    WaterName = aNames[i];
    
	// Add watermark
    event.target.addWatermarkFromText({
        cText: WaterName,
        nTextAlign:app.constants.align.center,
        cFont: "Arial",
        nScale: -1,
        nRotation: 45,
        nOpacity: 0.06
    });

	// Build File Name addition from Name
    var cExt = (" - " + WaterName + ".pdf");

    //Add the extension to the end of the file name and create save path
    var cDstName = event.target.documentFileName.replace(/\.pdf$/,cExt);
    var cDstPath = "/Users/Ben/Desktop/" + cDstName;

    // Save the file and close
    event.target.saveAs(cDstPath); 
    event.target.closeDoc();
    
    // Open CleanFile
	app.openDoc(CurPDF);
    
}