Adobe Illustratorの単純作業はこれにお任せ!テンプレート流し込みスクリプト
こんにちは、プログラマの矢野です。先日、テンプレートの流し込みを行うIllustratorスクリプトを作成しました。
Illustratorスクリプトとは
IllustratorスクリプトとはIllustratorの機能のひとつで、スクリプトを使うと、ひとまとまりの操作を自動的に処理させることが出来ます。この操作はIllustrator内だけでなく、Excell、Wordなど、ほかのアプリケーションと連動することもあります。
Illustratorには、はじめからJavaScript、AppleScript、ExtendScriptなど複数のスクリプト環境がサポートされていて、独自に作成したスクリプトをメニューに追加することもできます。
今回作成したスクリプトの作業内容をご紹介します。
テンプレートの作成
まずはIllustratorでテンプレートを作成するところから、使い方を順に説明します。

画像表示領域となる長方形を作成します。後で配置する画像をここにクリッピングマスクします。

次にテキストを作成します。今回は日付とコメントを表示させたいので、dateとcommentという2つのテキストを作成しました。

次に作成した長方形とテキストをまとめて選択して、メニューのオブジェクト/グループでグループ化します。

作成したグループオブジェクトをコピーして、アートワークに配置していきます。今回は12個のグループオブジェクトを配置しました。これでテンプレートの完成です。
変数の作成
スクリプトからIllustratorオブジェクトにアクセスできるように変数を追加していきます。

メニューのウィンドウから変数パネルを表示します。

CSVデータを流し込みたい順番にグループオブジェクトを選択して、変数パネルの下にある「表示を動的に設定」アイコンを選択します。

変数パネルに変数1という変数名ができました。オブジェクト項目には<グループ>と表示されています。選択したグループオブジェクトに変数1という変数を紐付けました。

各グループオブジェクトに変数を設定していきます。今回は12個のグループオブジェクトがありましたので、変数1~変数12が作成されました。
ここで重要なのが、CSVデータは一番上の変数1から順番に流し込まれるということです。CSVデータを流し込む順番にグループオブジェクトを指定して、変数を作成していきます。

変数パネルの項目をMacならcommandキー、WindowsならCtrlキーを押しながら選択すると、その変数のグループオブジェクトが選択されるので、各変数に紐付けられているグループオブジェクトを確認することができます。
これで変数の作成は完成です。
CSVファイルの作成
ExcelやGoogleのスプレッドシートなどで表を作成します。

一番上の列に項目名を入力します。テキストの項目名はIllustratorで作成したテンプレートのテキスト内容と一致する必要があります。
今回はdateとcommentという2つのテキストを用意しましたので、項目名もdateとcommentにします。画像の項目名の指定はありません。
画像ファイル名はIllustratorで作成したテンプレートファイルから見た相対パスを入力していきます。今回はテンプレートファイルと同じ階層に画像ファイルを置いています。

次に作成した表をCSVファイルに変換します。CSVのフォーマットはカンマ(,)区切りで、エンコードはUTF-8で保存します。
スクリプトの実行
Illustratorで作成したテンプレートファイルを開き、スクリプトを実行します。
作成したスクリプトは以下のものになります。
(function() {
var CSVConverter = function() {
this.lines = [];
this.textGroups = [];
this.pathGroups = [];
this.textWords = null;
this.variables = app.activeDocument.variables;
this.path = String(app.documents[0].fullName).replace(app.documents[0].name, "");
//CSVの何列目に画像ファイルの項目があるか
this.imageIndex = 3; //3列目
for (var i = 0, n = this.variables.length; i < n; i++) {
var group = this.variables[i].pageItems[0];
if (group.textFrames.length != 0) {
this.textGroups.push(group);
}
}
for (i = 0, n = this.variables.length; i < n; i++) {
group = this.variables[i].pageItems[0];
if (group.pathItems.length != 0) {
this.pathGroups.push(group);
}
}
};
CSVConverter.prototype = {
read: function() {
var path = File.openDialog("CSVファイルを選択してください。");
if (! path) {
return;
}
var csv = new File(path);
if (! csv.open("r", "", "")) {
return;
}
this.lines = [];
var text = csv.read();
var lines = text.split(String.fromCharCode(10));
for (var i = 0, n = lines.length; i < n; i++) {
var line = lines[i];
if (! line) {
continue;
}
if (i == 0) {
this.textWords = line.split(",");
} else {
this.lines.push(line.split(","));
}
}
csv.close();
},
writeText: function() {
for (var i = 0, n = this.textGroups.length; i < n; i++) {
var textFrames = this.textGroups[i].textFrames;
for (var j = 0, o = textFrames.length; j < o; j++) {
try {
var textFrame = textFrames[j];
var text = String(textFrame.contents);
for (var key in this.textWords) {
if (text.indexOf(this.textWords[key]) != -1) {
textFrame.contents = this.lines[i][key];
}
}
} catch (e) {}
}
}
},
writeImage: function() {
for (var i = 0, n = this.pathGroups.length; i < n; i++) {
var groups = this.pathGroups[i];
var paths = [];
if (groups.pathItems.length != 0) {
paths = groups.pathItems;
}
for (var j = 0, o = paths.length; j < o; j++) {
try {
var rect = paths[j];
var file = new File(this.path + this.lines[i][this.imageIndex - 1]);
var pItem = activeDocument.placedItems.add();
pItem.file = file;
this._createPosition(pItem, rect);
var mask = activeDocument.pathItems.rectangle(rect.top, rect.left, rect.width, rect.height);
mask.stroke = true;
mask.filled = true;
var holder = app.activeDocument.groupItems.add();
pItem.move(holder, ElementPlacement.PLACEATEND);
mask.move(holder, ElementPlacement.PLACEATBEGINNING);
holder.clipped = true;
rect.remove();
} catch (e) {}
}
}
},
_createPosition: function(targetA, targetB) {
var widthA = targetA.width;
var widthB = targetB.width;
var heightA = targetA.height;
var heightB = targetB.height;
targetA.left = targetB.left;
targetA.top = targetB.top;
if (widthA > widthB) {
targetA.left = targetA.left - ((widthA - widthB) / 2);
}
if (heightA > heightB) {
targetA.top = targetA.top + ((heightA - heightB) / 2);
}
}
};
var converter = new CSVConverter();
converter.read();
converter.writeText();
converter.writeImage();
})();

メニューからファイル/スクリプト/その他のスクリプトを選択します。

「実行するスクリプトファイルの場所」ダイアログボックスが開きますので、実行するスクリプトのファイルを選択します。
今回はCSVConverter.jsを選択します。

次に「CSVファイルを選択してください」というダイアログボックスが開きますので、使用するCSVファイルを選択します。
今回はtest.csvを選択します。

スクリプトが実行され、CSVの内容がIllustratorのテンプレートファイルに流し込まれます。
スクリプトの利点
宛名や名刺といった、同じレイアウトのものを複数作成する際、テンプレートを用意してこのスクリプトを使用すれば、作業が効率化できます。今回使用したサンプルは、下記からダウンロードできますので、皆さまもぜひ試してみてください。
*
私たちは、このような社内勉強会を定期的に開催し技術向上に勤しんでおります。向上心が豊かで私たちの仲間になってくれるデザイナーやディレクター、エンジニアを随時募集しております。我こそはと思われる方のご応募を心よりお待ちしております。
また、ブランディングについて詳しく知りたい方は下記をご覧ください。
ブランディングについて | ブランコ株式会社
CSVファイルの作成
(function() {
var CSVConverter = function() {
this.lines = [];
this.textGroups = [];
this.pathGroups = [];
this.textWords = null;
this.variables = app.activeDocument.variables;
this.path = String(app.documents[0].fullName).replace(app.documents[0].name, "");
//CSVの画像ファイル名項目の列数
this.imageIndex = 3;
for (var i = 0, n = this.variables.length; i < n; i++) {
var group = this.variables[i].pageItems[0];
if (group.textFrames.length != 0) {
this.textGroups.push(group);
}
}
for (i = 0, n = this.variables.length; i < n; i++) {
group = this.variables[i].pageItems[0];
if (group.pathItems.length != 0) {
this.pathGroups.push(group);
}
}
};
CSVConverter.prototype = {
read: function() {
var path = File.openDialog("CSVファイルを選択してください。");
if (! path) {
return;
}
var csv = new File(path);
if (! csv.open("r", "", "")) {
return;
}
this.lines = [];
var text = csv.read();
var lines = text.split(String.fromCharCode(10));
for (var i = 0, n = lines.length; i < n; i++) {
var line = lines[i];
if (! line) {
continue;
}
if (i == 0) {
this.textWords = line.split(",");
} else {
this.lines.push(line.split(","));
}
}
csv.close();
},
writeText: function() {
for (var i = 0, n = this.textGroups.length; i < n; i++) {
var textFrames = this.textGroups[i].textFrames;
for (var j = 0, o = textFrames.length; j < o; j++) {
try {
var textFrame = textFrames[j];
var text = String(textFrame.contents);
for (var key in this.textWords) {
if (text.indexOf(this.textWords[key]) != -1) {
textFrame.contents = this.lines[i][key];
}
}
} catch (e) {}
}
}
},
writeImage: function() {
for (var i = 0, n = this.pathGroups.length; i < n; i++) {
var groups = this.pathGroups[i];
var paths = [];
if (groups.pathItems.length != 0) {
paths = groups.pathItems;
}
for (var j = 0, o = paths.length; j < o; j++) {
try {
var rect = paths[j];
var file = new File(this.path + this.lines[i][this.imageIndex - 1]);
var pItem = activeDocument.placedItems.add();
pItem.file = file;
this._createPosition(pItem, rect);
var mask = activeDocument.pathItems.rectangle(rect.top, rect.left, rect.width, rect.height);
mask.stroke = true;
mask.filled = true;
var holder = app.activeDocument.groupItems.add();
pItem.move(holder, ElementPlacement.PLACEATEND);
mask.move(holder, ElementPlacement.PLACEATBEGINNING);
holder.clipped = true;
rect.remove();
} catch (e) {}
}
}
},
_createPosition: function(targetA, targetB) {
var widthA = targetA.width;
var widthB = targetB.width;
var heightA = targetA.height;
var heightB = targetB.height;
targetA.left = targetB.left;
targetA.top = targetB.top;
if (widthA > widthB) {
targetA.left = targetA.left - ((widthA - widthB) / 2);
}
if (heightA > heightB) {
targetA.top = targetA.top + ((heightA - heightB) / 2);
}
}
};
var converter = new CSVConverter();
converter.read();
converter.writeText();
converter.writeImage();
})();
(function() {
var CSVConverter = function() {
this.lines = [];
this.textGroups = [];
this.pathGroups = [];
this.textWords = null;
this.variables = app.activeDocument.variables;
this.path = String(app.documents[0].fullName).replace(app.documents[0].name, "");
//CSVの画像ファイル名項目の列数
this.imageIndex = 3;
for (var i = 0, n = this.variables.length; i < n; i++) {
var group = this.variables[i].pageItems[0];
if (group.textFrames.length != 0) {
this.textGroups.push(group);
}
}
for (i = 0, n = this.variables.length; i < n; i++) {
group = this.variables[i].pageItems[0];
if (group.pathItems.length != 0) {
this.pathGroups.push(group);
}
}
};
CSVConverter.prototype = {
read: function() {
var path = File.openDialog("CSVファイルを選択してください。");
if (! path) {
return;
}
var csv = new File(path);
if (! csv.open("r", "", "")) {
return;
}
this.lines = [];
var text = csv.read();
var lines = text.split(String.fromCharCode(10));
for (var i = 0, n = lines.length; i < n; i++) {
var line = lines[i];
if (! line) {
continue;
}
if (i == 0) {
this.textWords = line.split(",");
} else {
this.lines.push(line.split(","));
}
}
csv.close();
},
writeText: function() {
for (var i = 0, n = this.textGroups.length; i < n; i++) {
var textFrames = this.textGroups[i].textFrames;
for (var j = 0, o = textFrames.length; j < o; j++) {
try {
var textFrame = textFrames[j];
var text = String(textFrame.contents);
for (var key in this.textWords) {
if (text.indexOf(this.textWords[key]) != -1) {
textFrame.contents = this.lines[i][key];
}
}
} catch (e) {}
}
}
},
writeImage: function() {
for (var i = 0, n = this.pathGroups.length; i < n; i++) {
var groups = this.pathGroups[i];
var paths = [];
if (groups.pathItems.length != 0) {
paths = groups.pathItems;
}
for (var j = 0, o = paths.length; j < o; j++) {
try {
var rect = paths[j];
var file = new File(this.path + this.lines[i][this.imageIndex - 1]);
var pItem = activeDocument.placedItems.add();
pItem.file = file;
this._createPosition(pItem, rect);
var mask = activeDocument.pathItems.rectangle(rect.top, rect.left, rect.width, rect.height);
mask.stroke = true;
mask.filled = true;
var holder = app.activeDocument.groupItems.add();
pItem.move(holder, ElementPlacement.PLACEATEND);
mask.move(holder, ElementPlacement.PLACEATBEGINNING);
holder.clipped = true;
rect.remove();
} catch (e) {}
}
}
},
_createPosition: function(targetA, targetB) {
var widthA = targetA.width;
var widthB = targetB.width;
var heightA = targetA.height;
var heightB = targetB.height;
targetA.left = targetB.left;
targetA.top = targetB.top;
if (widthA > widthB) {
targetA.left = targetA.left - ((widthA - widthB) / 2);
}
if (heightA > heightB) {
targetA.top = targetA.top + ((heightA - heightB) / 2);
}
}
};
var converter = new CSVConverter();
converter.read();
converter.writeText();
converter.writeImage();
})();



