Copy link to clipboard
Copied
Hi there,
Is there any way to resize objects with variable data in Illustrator? I have a pdf file with rectangles. I want to change rectangle dimensions with variable data. Is this possible to do?
Thanks!
To get the csv file at runtime with a modal dialog, use this:
var csvFile = File.openDialog("Select CSV File");
To convert mm to points, use this:
function mmToPt(mm)
{
return mm * 2.834645669391;
}
var myObj = app.activeDocument.pageItems[0];
myObj.width = mmToPt(50); // set width to 50 mm
myObj.height = mmToPt(100); // set height to 100mm
updated code on github:
https://github.com/wdjsdev/public_illustrator_scripts/blob/master/resize_with_variable_data.js
Copy link to clipboard
Copied
please describe what you need in more detail. Post screen shots or better yet sample files.
Copy link to clipboard
Copied
As Carlos mentioned, we don't really have enough information to go on. But I figured I'd take a stab at it anyway.
/*
Script Name: resize with variable data
Author: William Dowling
Paypal: paypal.me/illustratordev
Description: Given a csv file, find and
resize any objects in the document
matching the name in the first column
of the csv.
Sample of expected CSV formatting:
Name,Width,Height
myItem1,95,85
Second Item,120,45
Other Item Name,50,50
*/
#target Illustrator
function resizeWithVariableData()
{
var doc = app.activeDocument;
var layers = doc.layers;
var csvFile = File("~/Desktop/my_csv.csv");
csvFile.open("r");
var csvContents = csvFile.read();
csvFile.close();
var rows = csvContents.split("\n");
var splitRow,curRect;
for(var x=1;x<rows.length;x++)
{
splitRow = rows[x].split(",");
try
{
curRect = doc.pageItems[splitRow[0]];
curRect.width = splitRow[1];
curRect.height = splitRow[2];
}
catch(e)
{
alert("Failed to find a pageItem called: " + splitRow[0]);
}
}
}
resizeWithVariableData();
https://github.com/wdjsdev/public_illustrator_scripts/blob/master/resize_with_variable_data.js
Copy link to clipboard
Copied
Hi there,
Thank you very much for the answer! Despite I couldn't manage to run the script, it's exaclty what I am looking for to achive.
To be more clear, I attached the file I'm working. You'll see 6 rectangles. Currently, I am using VariableDataImporter script to place images inside of these rectangles. What I'm trying to do is transform them, with the reference point set bottom left, then use VariableDataImporter to replace my images in resized rectangles. I think I missed something when I tried to run your script. I made this csv file (attached), then change file path on the script:
var csvFile = File("/Users/tugberkdilbaz/Desktop/abc.csv");
Maybe this is where I get stuck. I'm using Mac. I copied file path with "Copy as Path Name" command. It didn't seem to work. Thanks again for your help!
Copy link to clipboard
Copied
Did you get an error? Or were the results simply not what you expected? what happened during/after the script? Are you sure there's a rectangle in the file called "img1"?
is that csv file the exact file you're using? if so, you need to have a "title row" like in my example. the first line should describe what's going to be in each column. This isn't strictly necessary for the functionality to work, but it's good practice so that when you look at your CSV later, you'll still remember what the columns represent.. I think the problem is that the loop that parses the CSV data is never executing because it starts at the second row (in order to skip the title row), and you don't have a second row, so the loop condition is never true.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
none of your rectangles are named. the script needs to be able to identify a specific rectangle so it can resize it.
It's also possible to just loop them sequentially if you can be confident that the stacking order (in the layers panel) matches the csv. That would preclude the need for naming the rectangles, but it may cause some inconsistency if the stacking order isn't the same.
i used your example file, renamed the rectangle clip groups to "img1" through "img6" and duplicated your csv to account for each one and it worked swimmingly for me.
Updated code (with proper bottom left scale point) is on github at the same link i sent earlier).f
Copy link to clipboard
Copied
Still no lock. Am I doing something wrong while renaming layers? You can see I use linked-pdf files for rectangles. Even I tried to embed these files, and rename groups like you did. It didn't work. I attached screenrecording how I create my example pdf file. I hope it's more clear. Thanks again!
Copy link to clipboard
Copied
Can you send that test file you're using for the script so I can test it on my end and inspect the layer/object structure?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
i see now. The problem is the quotes in your CSV file.
The script is looking for a pageItem called "img1, including that quote, which doesn't match any items in your document. a csv file is already a text document, so there's no need for quotes. It'll be converted to a string object when it's read into the csvContents variable.
I've made a more robust version of this including some better error handling and a less error prone method of finding items by name.
https://github.com/wdjsdev/public_illustrator_scripts/blob/master/resize_with_variable_data.js
/*
Script Name: resize with variable data
Author: William Dowling
Paypal: paypal.me/illustratordev
Description: Given a csv file, find and
resize any objects in the document
matching the name in the first column
of the csv.
Sample of expected CSV formatting:
Name,Width,Height
myItem1,95,85
Second Item,120,45
Other Item Name,50,50
*/
#target Illustrator
function resizeWithVariableData()
{
//function for finding a specific item inside a parent container
//parent = container object
//itemName = string
//[crit] = string representing criteria for a match
//"match" means the entire name must match exactly
//"imatch" means name must match, but case doesn't matter
//"any" means itemName must exist somewhere in curItem.name, case insensitive
//return a single object or undefined
//Note: it will only find the FIRST item that matches. if there are multiple
//items with the same name, this function doesn't know about any subsequent matching items
function findSpecificPageItem(parent,itemName,crit)
{
var result,curItem;
if(parent.pageItems.length)
{
for(var x=0,len=parent.pageItems.length;x<len && !result;x++)
{
curItem = parent.pageItems[x];
if(crit)
{
if(crit === "match" && curItem.name === itemName)
{
result = curItem;
}
else if(crit === "imatch" && curItem.name.toLowerCase() === itemName.toLowerCase())
{
result = curItem;
}
else if(crit === "any" && curItem.name.toLowerCase().indexOf(itemName.toLowerCase())>-1)
{
result = curItem;
}
}
else if(curItem.name === itemName)
{
result = curItem;
}
}
}
return result;
}
var doc = app.activeDocument;
var layers = doc.layers;
//change this path to match the location of your csv
// var pathToCSV = "/Users/tugberkdilbaz/Desktop/abc.csv"
var pathToCSV = "~/Desktop/test/abc.csv";
var csvFile = File(pathToCSV);
if(csvFile.exists)
{
csvFile.open("r");
var csvContents = csvFile.read();
csvFile.close();
}
else
{
alert("No CSV File found at " + pathToCSV);
return;
}
if(!csvContents || csvContents === "" || (csvContents.indexOf(",")<0 && csvContents.indexof(";")<0))
{
alert("Invalid CSV formatting.");
return;
}
var missingItems = [];
var rows = csvContents.split("\n");
var splitRow,curRect,curPos = [];
for(var x=1;x<rows.length;x++)
{
splitRow = rows[x].split(",");
curRect = findSpecificPageItem(doc,splitRow[0],"any");
if(curRect)
{
curPos = [curRect.left,curRect.top - curRect.height];
curRect.width = splitRow[1];
curRect.height = splitRow[2];
curRect.left = curPos[0];
curRect.top = curPos[1] + curRect.height;
}
else
{
missingItems.push(splitRow[0]);
}
}
if(missingItems.length)
{
alert("The following items were listed on the CSV, but were not found in the document:\n" + missingItems.join("\n"));
}
}
resizeWithVariableData();
Copy link to clipboard
Copied
Thank you so much, it worked! I didn't notice " marks, because I created csv file using Google Sheets. I have another question, what type of units we're setting with the script? Can I enter width and height as milimeters? Also is there a any way to selecting csv file instead of giving path link inside of the script? Thanks again, this helped me a lot!
Copy link to clipboard
Copied
For sure. Script units in illustrator are in "points". The conversion to inches is 72:1 (72 points = 1 inch). I don't know the conversion to mm since I don't use those units regularly, but if you figure out how many mm are in an inch, then you can do the math. I don't have time at the moment, but I'll come bakc later with an equation to figure that out.
It's also pretty simple to create a file select dialog so you can choose your pdf at runtime. I'll show you how to do that as well when I have a moment.
Copy link to clipboard
Copied
That would be great if you can help with select dialog. I'll be waiting, thank you very much again!
Copy link to clipboard
Copied
To get the csv file at runtime with a modal dialog, use this:
var csvFile = File.openDialog("Select CSV File");
To convert mm to points, use this:
function mmToPt(mm)
{
return mm * 2.834645669391;
}
var myObj = app.activeDocument.pageItems[0];
myObj.width = mmToPt(50); // set width to 50 mm
myObj.height = mmToPt(100); // set height to 100mm
updated code on github:
https://github.com/wdjsdev/public_illustrator_scripts/blob/master/resize_with_variable_data.js
Copy link to clipboard
Copied
Thanks a lot, this worked perfectly. It saved me lots time! Thanks again!