Copy link to clipboard
Copied
I have a pdf document with a graph containing a line of two digit values (17 of them), e.g.,
74 63 59 72 ...
I have written a program that checks each value against a specified value to determine if the displayed calue is greater than the specified one. If it is, I need to draw a red box arouund the displayed value to indicate it exceeds the specified one. If not possible, I need some way to indicate the exceptions, e.g., changing the font color for that displayed value. VBA, Javascript, or a language suggested by you are all acceptable.
Copy link to clipboard
Copied
Are the values in form fields?
Copy link to clipboard
Copied
No
Copy link to clipboard
Copied
Use the comment markup "Square" tool and draw a box. Then, name the annotation by selecting it and running the following script in the console (name example is "Square1"):
this.selectedAnnots[0].name="Square1";
Also, make it "readonly" so that it can't be resized, moved, or deleted by the end user by running the following script in the console:
this.selectedAnnots[0].readOnly=true;
Also, add the display value to it's contents like this:
this.selectedAnnots[0].contents="72";
Hide the annotation by running the following script in the console:
this.selectedAnnots[0].hidden=true;
Change the hidden property of the annotation to true or false in your calculation, calling it by its name like this:
var anot=this.getAnnot(0,"Square1");
if(75>Number(anot.contents))
{anot.hidden=false}
else
{anot.hidden=true}
Note, the 0 before "Square1" is the page index of the annotation (page 1 in this case).
Copy link to clipboard
Copied
A clarification seems necessary. All of the actions described need to be done in code. The 17 two digit values are near the botton of an existing one page pdf file. My vba program reads the 17 values from an accompanying csv file and determines for each one if exceeds an associated known value. A program then needs to draw a thin line red box around the offending value. The program loops through the values until all 17 have been read and acted upon if exceeding the associated known value. I have suuccessfullyy drawn the boxes using Word to read the pdf and draw the boxes before converting the document back to a pdf file. However, Word sometimes alters the layout of the page slighly which forces the one page pdf to become a two page pdf. This poses problems beyond the scope of this request.
Copy link to clipboard
Copied
You can isolate the 17 values by cropping the page. Then read the words (values) and compare them to the known value. Then draw the boxes around the words with a script, reverse crop the page, and flatten the PDF.
Copy link to clipboard
Copied
As stated above, I already know which of the 17 need to have a red box drawn around them because that same data is in a csv file. What I do not know how to do is to programmatically draw the red boxes around the correct boxes while in Acrobat rather than in Mcirosoft Word whcih often distorts the layout of the page containing the 17 valuues.
Copy link to clipboard
Copied
It would be helpful if you upload and example. The Acrobat document methods to use are:
getPageNthWord (reads the Nth word on a page)
getPagePageNumWords (gets the number of words on a page)
getPageNthWordQuads (gets the quads list for the Nth word on the page)
addAnnot (adds an annotation)
Here's the process:
function drawSquare(oDoc,pg,val)
{
for(var i=0;i<oDoc.getPageNumWords(pg);i++)
{
if(oDoc.getPageNthWord(pg,i,false).trim()==val)
{
var qd=oDoc.getPageNthWordQuads(pg,i);
var anot = oDoc.addAnnot({
page:pg,
type:"Highlight",
quads:qd
});
var rc=anot.rect;
anot.destroy();
oDoc.addAnnot({
page:pg,
type:"Square",
rect: rc,
width:0.5
});
this.flattenPages(pg,pg);
}
}
}
//call function like this:
drawSquare(this,0,"35");
In the last line, 0 is the page index number and "35" is the value to draw the box around. If you want the red box thicker, increase the width property of the annotation from 0.5;
Copy link to clipboard
Copied
Thank you. I will give this a try although I am not a JavaScript expert.
Copy link to clipboard
Copied
Copy and paste the script into the console, changing only the "35" in the last line to the actual number you want to draw the box around, then run the script. If it's not always on page 1, change the 0 in the last line to oDoc.pageNum and it will search the current page. If you want to add the crop/reverse crop, add the crop at the beginning of the function and the reverse before flattenPages using the instructions in the this article:
https://pdfautomationstation.substack.com/p/cropping-and-reverse-cropping-pdf
To draw all the boxes, create an array of values to search for, then loop through the array and apply the function call to each array element.
Copy link to clipboard
Copied
I discovered a significant difference between what I initially submitted as the problem and what I should have included in that description. The numbers appear within an image so I cannot search for a number to place the red square around. I have another source for the numbers so I know which ones need the red square. I also have the x coordinate of the upper left corner of the square to be drawn. The square is to be 10x10. The x coordinates of the ones needing a square are contained in an array, let's say a varaible called 'boxes'. I have sample code below that I tried with the page # and coordinates contained as constants. This code does not work. I need a modification thereof or a new set of code to draw the boxes based on the array which will be passed to the code.
const color = {
red: [1, 0, 0], // RGB representation
};
let doc = this; // Ensure 'this' is referencing the correct object
// Define the array of coordinates
let coordinates = [
[0, 100, 200], // Page 0, X = 100, Y = 200
[0, 150, 250], // Page 0, X = 150, Y = 250
[0, 50, 300] // Page 0, X = 50, Y = 300
];
// Define the elements you want to process
let selectedIndices = [0, 2]; // Use the 1st and 3rd elements (index 0 and 2)
// Constants
const SQUARE_SIZE = 10; // Size of the square
// Loop through the selected indices
for (let i = 0; i < selectedIndices.length; i += 1) {
let idx = selectedIndices[i];
// Get the page number, x, and y coordinates
let page = coordinates[idx][0];
let x = coordinates[idx][1];
let y = coordinates[idx][2];
// Define the rectangle for the red square
let rect = [x, y - SQUARE_SIZE, x + SQUARE_SIZE, y];
// Draw a red square at the specified coordinates
doc.addAnnot({
type: "Square",
page: page,
rect: rect,
strokeColor: color.red,
borderWidth: 1
});
}
Copy link to clipboard
Copied
Try this:
var cords=[
[0,100,200],
[0, 150, 250],
[0, 50, 300]
];
for(var i=0; i<cords.length; i++)
{
this.addAnnot({
type:"Square",
page:cords[i][0],
rect:[cords[i][1],cords[i][2]-10,cords[i][1]+10,cords[i][2]],
strokeColor:color.red,
borderWidth:1
});
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Copy link to clipboard
Copied
i ran it by opening the pdf file in Acrobat Pro. I then pressed Ctrl-J to open the JavaScript window. I pasted the code into the console and pressed Ctrl-Enter. How did you run it?
Copy link to clipboard
Copied
Exactly like you described, except you need to first select the entire code. If not, it will only run one line of code (the one the cursor is on).
Copy link to clipboard
Copied
Thank you! That did it. A further question: how do I now programmaticly open the pdf file, insert this JavaScript, run it, and save the modified file with the same or a different name?
Copy link to clipboard
Copied
You need a trigger. It can be custom menu item, a custom toolbar button, or an Action. Actions are a privileged context so you don't need a trusted function. To save the modified file add the following script to the end of the script:
this.saveAs(this.path);
For the menu item and toolbar button you need a trusted function to save 'silently' (without further user interaction). I created a (paid for) tool to create custom toolbar buttons with icons if you're interested.
Copy link to clipboard
Copied
Thanks for the additional info. The opening of the pdf file and the running of the script above all msut be done via a program as the user is not interacting with the document or the menu ... at any time.In fact, a series of documents are being processed in a similar fashion. I was hoping the API would help me in this regard but so far have not found a way to do so.
Copy link to clipboard
Copied
Running JavaScripts in Acrobat on PDFs require some interaction from the user.
Copy link to clipboard
Copied
If drawing the red boxes is possible via the API/SDK, I am willing to pay to have it created.
Copy link to clipboard
Copied
Please contact me privately by clicking my avatar then "Send Message".