Copy link to clipboard
Copied
Can anyone tell me if there is a way to generate multiple shapes simultaneously using WIDTH x HEIGHT from a CSV worksheet of dimensions? Similar to the way varaiable data is used in Adobe Illustrator. The attached image describes a more detailed process with letters and saving but I'd like to just find a way to accomplish making the shapes. I basiclly have a list of W x H dimensions and need way to generate a lot of boxes with a single task. I only need to process around 10 shapes at a time but I need to do about 5K shapes all with different dimensions. Entering every value manually will take forever and I was hoping to automate this task.
Here is a simple example which you or someone else could edit or use as starting point.
#target illustrator
function test () {
var COL_NAME = 0;
var COL_WIDTH = 1;
var COL_HEIGHT = 2;
var OUTPUT_DIR = "~/Desktop/Ai Forums Test 08212020";
var csvFile = File.openDialog("Choose CSV file.", "*.csv");
var csvContents = "";
if (csvFile) {
csvFile.open('r');
csvContents = csvFile.read();
csvFile.close();
} else {
return;
}
var csvData = csvContents.split(/[\r\n]
...
...added Letters to sillyV's script
function test () {
var COL_NAME = 0;
var COL_WIDTH = 1;
var COL_HEIGHT = 2;
var COL_CHAR = 3;
var OUTPUT_DIR = "~/Desktop/Ai Forums Test 08212020";
Folder(OUTPUT_DIR).create();
var csvFile = File.openDialog("Choose CSV file.", "*.csv");
var csvContents = "";
if (csvFile) {
csvFile.open('r');
csvContents = csvFile.read();
csvFile.close();
}
var csvData = csvContents.split(/[\r\n]+/g);
var thisRow;
for (var i = 0; i < csvData.
...
Copy link to clipboard
Copied
I don't think you can generate a rectangle with specific WxH using Variable Data. But you can using Scripting. If you know how to program and want to write a script yourself, I can point you where to download the documentation.
Copy link to clipboard
Copied
Thx Carlos
I don't know how to script. I've spent a lifetime creating artwork in Adobe's GUI world so all my experience is pretty surface visuals. I'm handy enough to come up with workarounds and smart/dangerous enough not to try too often. This is something that is over my head.
If you can point me in any direction it would be greatly appreciated. Not sure what to search to find a solution and Frankenstein something simple for myself.
I've tried:
I even stalked you read your posts and found your script for doing page numbering in illustrator [PS can I exchange numbers for letters] to incorporate into this project.
I found a simple code for building SVG shapes online [see code below] from w3schools.com but don't understand how to build an interface to easily cut and paste the W x H data to generate the boxes.
I've found bits and pieces but I don't know what to search to get the results. Surprised I'm the only one who needs to do something like this.
<html>
<body>
<svg width="20" height="50">
<rect width="20" height="30" style="fill:cmyk(0,0,0,0)" />
Sorry, your browser does not support inline SVG.
</svg>
<svg width="20" height="50">
<rect width="20" height="30" style="fill:cmyk(0,0,0,0)" />
Sorry, your browser does not support inline SVG.
</svg>
<svg width="20" height="50">
<rect width="20" height="30" style="fill:cmyk(0,0,0,0)" />
Sorry, your browser does not support inline SVG.
</svg>
</body>
</html>
Copy link to clipboard
Copied
Here is a simple example which you or someone else could edit or use as starting point.
#target illustrator
function test () {
var COL_NAME = 0;
var COL_WIDTH = 1;
var COL_HEIGHT = 2;
var OUTPUT_DIR = "~/Desktop/Ai Forums Test 08212020";
var csvFile = File.openDialog("Choose CSV file.", "*.csv");
var csvContents = "";
if (csvFile) {
csvFile.open('r');
csvContents = csvFile.read();
csvFile.close();
} else {
return;
}
var csvData = csvContents.split(/[\r\n]+/g);
var thisRow;
for (var i = 0; i < csvData.length; i++) {
thisRow = csvData[i];
csvData[i] = thisRow.split(",");
}
var workDoc = app.documents.add();
var thisRecord, w, h, name, newRect;
var opts = new PDFSaveOptions();
for (var i = 1; i < csvData.length; i++) {
thisRecord = csvData[i];
name = thisRecord[COL_NAME];
w = thisRecord[COL_WIDTH] * 72;
h = thisRecord[COL_HEIGHT] * 72;
newRect = workDoc.pathItems.rectangle(0, 0, w, h);
newRect.selected = true;
workDoc.fitArtboardToSelectedArt(0);
newRect.stroked = false;
newRect.fillColor = workDoc.swatches.getByName("Black").color;
workDoc.saveAs(File(OUTPUT_DIR + "/" + name + ".pdf"), opts);
workDoc.pathItems[0].remove();
}
workDoc.close(SaveOptions.DONOTSAVECHANGES);
};
test();
It uses the following data csv:
And it makes the following pdfs:
Copy link to clipboard
Copied
Thanks Silly-V
This look amazing... I see you even converted it from inches to pixels which is great. I actually did that on my excel sheet but if the script does that, even better. Can I just use the script in my script editor and save it to test or do I need to modify it? Should I take out any parts to make it save? I tried just saving it and it said "Expected end of line, etc. but found identifier."
This simple thing you did is still over my head. I tried testing it in shellcheck.net but it was telling me to "Add a Shebang or 'shell' Directive"
Copy link to clipboard
Copied
If you can copy the text into notepad and save as .jsx, you can go from Illustrator File > Scripts > Other Scripts and choose this .jsx file wherever you saved it. Then it should run. I just tried to do this and it worked for me.
You should also be able to run it from the old ESTK or the VSCode Adobe plugin just fine.
Copy link to clipboard
Copied
This ran perfectly. Thanks again!
Had a follow-up question to the script. When the script asks to select the CSV file, how are the artboard specs defined? I see the script is using the W x H to create a rectangle and then using the
menu command to fitArtboardToSelectedArt.
Can the file specs be set to inches rather than pixels so you don't need to calculate from pixels to inches?
w = thisRecord[COL_WIDTH] * 72;
h = thisRecord[COL_HEIGHT] * 72;
Could the bleed area also be turned on to include a .25 bleed around the files?
Copy link to clipboard
Copied
Hi!
I have no experience with this script stuff and have gotten this one workin for me. In my case I'd like to have all of these squares exist in the same AI file instead of creating a new file for each square.
Would you be able to help me figure that out? thanks!
Copy link to clipboard
Copied
...added Letters to sillyV's script
function test () {
var COL_NAME = 0;
var COL_WIDTH = 1;
var COL_HEIGHT = 2;
var COL_CHAR = 3;
var OUTPUT_DIR = "~/Desktop/Ai Forums Test 08212020";
Folder(OUTPUT_DIR).create();
var csvFile = File.openDialog("Choose CSV file.", "*.csv");
var csvContents = "";
if (csvFile) {
csvFile.open('r');
csvContents = csvFile.read();
csvFile.close();
}
var csvData = csvContents.split(/[\r\n]+/g);
var thisRow;
for (var i = 0; i < csvData.length; i++) {
thisRow = csvData[i];
csvData[i] = thisRow.split(",");
}
var workDoc = app.documents.add();
var thisRecord, w, h, name, newRect, c;
var opts = new PDFSaveOptions();
var tframe = workDoc.textFrames.add();
for (var i = 1; i < csvData.length; i++) {
thisRecord = csvData[i];
name = thisRecord[COL_NAME];
w = thisRecord[COL_WIDTH] * 72;
h = thisRecord[COL_HEIGHT] * 72;
c = thisRecord[COL_CHAR];
newRect = workDoc.pathItems.rectangle(0, 0, w, h);
newRect.move(tframe, ElementPlacement.PLACEAFTER);
newRect.selected = true;
workDoc.fitArtboardToSelectedArt(0);
newRect.stroked = false;
tframe.contents = c;
tframe.textRange.characterAttributes.size = 48;
tframe.textRange.characterAttributes.fillColor = workDoc.swatches.getByName("White").color;
tframe.position = [newRect.left + newRect.width/2 - tframe.width/2, newRect.top - newRect.height/2 + tframe.height/2];
newRect.fillColor = workDoc.swatches.getByName("Black").color;
workDoc.saveAs(File(OUTPUT_DIR + "/" + name + ".pdf"), opts);
workDoc.pathItems[0].remove();
}
workDoc.close(SaveOptions.DONOTSAVECHANGES);
};
test();
Copy link to clipboard
Copied
Thanks so much Carlos. I took a look at the code to help me understand how you inserted the page numbering. I was able to increase the type size.
Copy link to clipboard
Copied
In the script, the artboard is defined by the newRect shape from the CSV file which is exactly what I need. Could I also like to insert another action [like Carlos did with the labels] to increase the newRect shape by .5 inches to the width and height just before the file is saved? This would make the shape bleed off the edge by .25
inches on every side.
Could I insert the code after this line:
newRect.fillColor = workDoc.swatches.getByName("Black").color;
Then use this to select the shape:
newRect.selected = true;
Not sure what to write after this increase the dimensions. I tried this:
newRect.width = +.5;
newRect.height = +.5;
...but it just trasformed the shapes into tiny 5 x 5 pixel boxes.
Copy link to clipboard
Copied
do you want to increase the rectangle size by 1/2" but keep the artboard size as is? or do you want to increase the artboard as well?
Copy link to clipboard
Copied
Just the rectangle size. The idea is to have artboard one size and rect 1/2" larger. The rect will extend and bleed off the artboard.
Copy link to clipboard
Copied
Hey Silly-V + Carlos,
I just marked this thread as solved. Thanks again for your help.
Let me know if there's an easy way to increase the size of the shape on the artboard. I wasn't sure how to reference the shape to increase it.
Copy link to clipboard
Copied
While it's possible to do this with just mathematically editing the artboard's artboardRect coordinates to get the fastest results, I wanted to revisit the liveEffectXml method of making offset paths since unfortunately a lot of old thread links are broken and I want to bump this feature for fun. Luckily I was able to find an old one that shows the offset path code!
function makeOffsetPathWithEffect (value, Path) {
var PathCopy = Path.duplicate();
var offsetvalueinput = value;
var liveXmlString = "<LiveEffect name='Adobe Offset Path'><Dict data='R mlim 4 R ofst " + offsetvalueinput + " I jntp 2 '/></LiveEffect>";
PathCopy.applyEffect(liveXmlString);
app.activeDocument.selection = null;
PathCopy.selected = true;
app.executeMenuCommand("expandStyle");
return app.activeDocument.selection[0];
};
var offsetRect = makeOffsetPathWithEffect(-0.25 * 72, app.activeDocument.pageItems[0]);
In this snippet you can see the function which you only need to paste at some point in your javascript code, and then you can call it similar to my example. The example creates a negative offset, but you can take away the minus to make it a positive. After this you would size the artboard to the offset copy and then remove the offset copy.
In the latest code , this is an example of how the function can be called inside there. I'm not sure what is being done with the stroke, so adjust as you will.
newRect = workDoc.pathItems.rectangle(0, 0, w, h);
newRect.move(tframe, ElementPlacement.PLACEAFTER);
newRect.stroked = false;
var rectOffsetCopy = makeOffsetPathWithEffect(0.2 * 72, newRect); // a 1/5th inch add
workDoc.fitArtboardToSelectedArt(0);
rectOffsetCopy.remove();
Copy link to clipboard
Copied
This is great...except it's doing the opposite of what I need. The code is making the artboard larger than the rect object. Is there a way to reverse the results and make the rect larger than the artboard? The rect should be an additional .25" from the dimensions on the CSV. That would make the rect bleed off the edges of the artboard by .25". I tried changing several things including the (-) and (+) of the .25" but I couldn't get it to config corectly. Here's what I have:
#target illustrator
function test () {
var COL_NAME = 0;
var COL_WIDTH = 1;
var COL_HEIGHT = 2;
var COL_CHAR = 3;
var OUTPUT_DIR = "~/Desktop/Artboards";
Folder(OUTPUT_DIR).create();
var csvFile = File.openDialog("Choose CSV file.", "*.csv");
var csvContents = "";
if (csvFile) {
csvFile.open('r');
csvContents = csvFile.read();
csvFile.close();
}
var csvData = csvContents.split(/[\r\n]+/g);
var thisRow;
for (var i = 0; i < csvData.length; i++) {
thisRow = csvData[i];
csvData[i] = thisRow.split(",");
}
var workDoc = app.documents.add();
var thisRecord, w, h, name, newRect, c;
var opts = new PDFSaveOptions();
var tframe = workDoc.textFrames.add();
for (var i = 1; i < csvData.length; i++) {
thisRecord = csvData[i];
name = thisRecord[COL_NAME];
w = thisRecord[COL_WIDTH] * 72;
h = thisRecord[COL_HEIGHT] * 72;
c = thisRecord[COL_CHAR];
function makeOffsetPathWithEffect (value, Path) {
var PathCopy = Path.duplicate();
var offsetvalueinput = value;
var liveXmlString = "<LiveEffect name='Adobe Offset Path'><Dict data='R mlim 4 R ofst " + offsetvalueinput + " I jntp 2 '/></LiveEffect>";
PathCopy.applyEffect(liveXmlString);
app.activeDocument.selection = null;
PathCopy.selected = true;
app.executeMenuCommand("expandStyle");
return app.activeDocument.selection[0];
};
var offsetRect = makeOffsetPathWithEffect(-0.25 * 72, app.activeDocument.pageItems[0]);
newRect = workDoc.pathItems.rectangle(0, 0, w, h);
newRect.move(tframe, ElementPlacement.PLACEAFTER);
newRect.stroked = false;
var rectOffsetCopy = makeOffsetPathWithEffect(0.25 * 72, newRect); // a 1/4 inch add
workDoc.fitArtboardToSelectedArt(0);
rectOffsetCopy.remove();
tframe.contents = c;
tframe.textRange.characterAttributes.size = 120;
tframe.textRange.characterAttributes.fillColor = workDoc.swatches.getByName("White").color;
tframe.position = [newRect.left + newRect.width/2 - tframe.width/2, newRect.top - newRect.height/2 + tframe.height/2];
newRect.fillColor = workDoc.swatches.getByName("Black").color;
workDoc.saveAs(File(OUTPUT_DIR + "/" + name + ".pdf"), opts);
workDoc.pathItems[0].remove();
}
workDoc.close(SaveOptions.DONOTSAVECHANGES);
};
test();
Copy link to clipboard
Copied
Using the -0.25 value should do what you want and shrink the copied rectangle so that when the next lines size down the artboard, it should be 0.25 smaller than the original rectangle.
Copy link to clipboard
Copied
So, this script has been working great so far but I was getting this error when I was creating some artboards that were larger. [see image below]. Funny enough when I reversed the W x H dimensions the scripted worked. Seems each board is being created in the center location of the file and when that dimension exceeds Ai's working area I am getting this error.
Is it possible to create the artboards in the far left top of Ai's working areas and have the boxes draw out from the top left? Or maybe correct from the center location when Ai goes beyond the art area. None of the dimensions I will use will exceed Ai's art area but some dimensions may be or exceed 120".
Wonder if this can be done. Thx
Copy link to clipboard
Copied
I think you may be able to set the ruler origin and thus create the art positioned from a new default xy location.
Unfortunately I can't make a test right now, maybe later - or maybe someone else will do it real quick before I get to it.
Copy link to clipboard
Copied
Thanks @Silly-V I totally understand. That bit of info was helpful. I found this Reset Origin
var doc = activeDocument;
doc.rulerOrigin = [0,doc.height]
but it doesn't seem to work when I insert it. Not sure how to edit to make it work. I've posted a reply on the other thread to see if there is a solutions. I realized that when the dimensions are over 114" [half the size of Ai's 227" limit] the artboard falls outside the working area.
Copy link to clipboard
Copied
Yea, I'm not sure what the procedure for that is, although it's probably just a 5 minute test and it's super useful. But due to laziness, I can tell you that you can create your new typical document and go all the way to the top left corner of the dark gray pasteboard. Record the distance in x and y directions from that point to your defautl artboard's top-left point. Now you can subtract these respective distances in your script code by substituting them in at this part:
.rectangle(0, 0