名刺制作で社員数が100名を超える案件になると、一名分ずつIllustratorで編集するのは非常に時間がかかります。今回はIllustratorの変数機能を利用し、CSVデータから名刺を一括生成する仕組みをまとめました。
Illustratorの変数機能に加えて、スクリプト(JavaScript)を利用することで、AIデータ(アウトライン化前)・お客様へ送付する校正用PDFをワンクリックで一括生成できるようにしています。今回は実際にやってみたので、その手順をまとめました。
記事は前編後編に記事をわけてまとめようと思います。
今回紹介する前編では、テンプレートデザインの作成〜お客様校正用PDFの一括出力まで、
後編は、校正後の入稿データの一括生成まで、を予定しています。
名刺テンプレートを作成
まずは、通常通り名刺デザインを作成します。
今回は、以下の情報を差し替える前提で作成しました。
② 氏名
③ メールアドレス
④ 電話番号

そのため、トンボの塗りたしが問題ないか、画像は埋め込まれているか、CMYK設定になっているかなど
のチェックはこの段階で済ませておいた方が安心です。
CSVを作成する
読み込むためのCSVを先に作成します。
CSVは変数名と完全一致させます。
今回は生成AIでダミー情報30名分を用意しました。

Illustratorに読み込む名刺情報を、Excelまたはスプレッドシートで作成します。
1行目には、Illustratorで設定した変数名を入力します。
変数名とCSVの見出しは、完全に一致させるのがポイントです。
ポイント
- 見出しは変数名と一致
- UTF-8保存
関連記事:CSVファイル作成時の注意点などはこちらでも詳しくご紹介しています!

CSVを読み込む
イラストレーターにCSVを取り込み、デザイン上の項目名との紐付けをしていきます。
① メニュー>ウィンドウ>変数 を表示すると、CSV読み込み画面になるので、あらかじめ用意しておいたCSVファイルを読み込みます。
② 読み込むと、「変数」という項目箇所に、CSVファイルの1行目に書いていた項目名が読み込まれます。
③ 名刺のデザインの該当するオブジェクトを選択し、変数パネルに表示されている一致する項目を選んだ状態で、右下にあるアイコン(「テキストを動的に設定」)というボタンをクリック。これで変数の紐付けができます。

データセットを確認
データセットを切り替えながら、読み込んだ情報が切り替わることを確認します。

⚠️ 私ははじめ、名刺のテンプレートデザイン側は「氏名」<—–> CSVファイルの項目名は「名前」にするなど、名称が一致していなかったため、データセットを切り替えようとすると、エラーがでてしまいました。

編集用AI・校正用PDFを一括生成
ここでスクリプトを実行します。今回作成したスクリプトでは下記のフォルダ構成でデータを自動で生成・振り分けします。
│
├─01_編集用AIフォルダ
└─02_校正用PDFフォルダ
※私はスクリプトを自作できないため、今回は完全にChatGPTが作成したものをそのまま活用しています。
#target illustrator
(function () {
if (app.documents.length === 0) {
alert("Illustratorで名刺テンプレートを開いてから実行してください。");
return;
}
var doc = app.activeDocument;
if (doc.dataSets.length === 0) {
alert("データセットがありません。CSVを読み込んでから実行してください。");
return;
}
// ファイル名に使う変数名。変数パネルの名称と完全一致させます。
var FILE_NAME_VARIABLE = "名前";
// 書き出すファイル名の先頭に付ける文字列
var FILE_NAME_PREFIX = "名刺データ_";
// 書き出し先の親フォルダを選択します。
// 選択したフォルダ内に「PDF」「AI」フォルダを自動作成します。
var rootFolder = Folder.selectDialog("PDF・AIデータの書き出し先フォルダを選択してください");
if (!rootFolder) {
return;
}
var pdfFolder = new Folder(rootFolder.fsName + "/PDF");
var aiFolder = new Folder(rootFolder.fsName + "/AI");
if (!pdfFolder.exists && !pdfFolder.create()) {
alert("PDFフォルダを作成できませんでした。");
return;
}
if (!aiFolder.exists && !aiFolder.create()) {
alert("AIフォルダを作成できませんでした。");
return;
}
// PDF保存設定
var pdfOptions = new PDFSaveOptions();
// プリントパック用に作成したPDFプリセットを使う場合は、次の行の
// コメントを外し、Illustratorに登録されているプリセット名へ書き換えてください。
// pdfOptions.pDFPreset = "プリントパック";
pdfOptions.preserveEditability = false;
pdfOptions.generateThumbnails = true;
pdfOptions.viewAfterSaving = false;
pdfOptions.saveMultipleArtboards = true;
// 表面がアートボード1だけの場合は "1"
// 表裏を2ページPDFにする場合は "1-2" に変更してください。
pdfOptions.artboardRange = "1";
// AI保存設定
var aiOptions = new IllustratorSaveOptions();
aiOptions.pdfCompatible = true;
aiOptions.compressed = true;
aiOptions.embedICCProfile = true;
var fileNameVariable = findVariableByName(doc, FILE_NAME_VARIABLE);
if (!fileNameVariable) {
alert(
"変数「" + FILE_NAME_VARIABLE + "」が見つかりません。\n" +
"スクリプト内のFILE_NAME_VARIABLEと変数パネルの名称を一致させてください。"
);
return;
}
if (fileNameVariable.pageItems.length === 0) {
alert("変数「" + FILE_NAME_VARIABLE + "」にテキストオブジェクトが割り当てられていません。");
return;
}
var pdfExportedCount = 0;
var aiExportedCount = 0;
var failed = [];
var originalDataSet = null;
try {
originalDataSet = doc.activeDataset;
} catch (e) {}
for (var i = 0; i < doc.dataSets.length; i++) { try { var dataSet = doc.dataSets[i]; // 対象のデータセットを表示 dataSet.display(); app.redraw(); // 「名前」変数に紐づくテキスト内容をファイル名に使用 var personName = getVariableText(fileNameVariable); if (!personName) { personName = dataSet.name || ("dataset_" + (i + 1)); } personName = sanitizeFileName(personName); var outputBaseName = FILE_NAME_PREFIX + personName; var aiFile = createUniqueFile(aiFolder, outputBaseName, ".ai"); var pdfFile = createUniqueFile(pdfFolder, outputBaseName, ".pdf"); // 先にAI、次にPDFを書き出します。 doc.saveAs(aiFile, aiOptions); aiExportedCount++; doc.saveAs(pdfFile, pdfOptions); pdfExportedCount++; } catch (e) { failed.push((i + 1) + "件目: " + e.message); } } // 可能であれば実行前のデータセット表示へ戻す try { if (originalDataSet) { originalDataSet.display(); app.redraw(); } } catch (e) {} var message = aiExportedCount + "件のAIデータと、" + pdfExportedCount + "件のPDFを書き出しました。\n\n" + "AI保存先:" + aiFolder.fsName + "\n" + "PDF保存先:" + pdfFolder.fsName; if (failed.length > 0) {
message += "\n\n書き出せなかったデータ:\n" + failed.join("\n");
}
message +=
"\n\n重要:開いているドキュメントの保存先が最後に書き出したPDFへ切り替わる場合があります。" +
"\nテンプレートAIは上書き保存せず、いったん閉じて元のAIファイルを開き直してください。" +
"\n\n書き出したAIには変数・データセット情報が残る場合がありますが、開いたときの表示は各人の内容になります。";
alert(message);
function findVariableByName(documentRef, variableName) {
for (var j = 0; j < documentRef.variables.length; j++) {
if (documentRef.variables[j].name === variableName) {
return documentRef.variables[j];
}
}
return null;
}
function getVariableText(variableRef) {
for (var j = 0; j < variableRef.pageItems.length; j++) { var item = variableRef.pageItems[j]; if (item.typename === "TextFrame") { return trimText(item.contents); } try { if (item.textFrames && item.textFrames.length > 0) {
return trimText(item.textFrames[0].contents);
}
} catch (e) {}
}
return "";
}
function sanitizeFileName(name) {
name = trimText(name);
name = name.replace(/[\\\/:\*\?"<>\|]/g, "_");
name = name.replace(/[\r\n\t]/g, "");
name = name.replace(/[ ]+/g, "");
name = name.replace(/\.+$/g, "");
if (!name) {
name = "name_unknown";
}
return name;
}
function createUniqueFile(folderRef, baseName, extension) {
var fileRef = new File(folderRef.fsName + "/" + baseName + extension);
var counter = 2;
while (fileRef.exists) {
fileRef = new File(folderRef.fsName + "/" + baseName + "_" + counter + extension);
counter++;
}
return fileRef;
}
function trimText(value) {
return String(value).replace(/^\s+|\s+$/g, "");
}
})();
① イラストレーターの「ファイル」>「スクリプト」>「その他のスクリプト」で、作成したスクリプトを指定します。
② 書き出しファイルの格納先を指定

レイアウト調整
CSVから生成すると、長い役職や長い氏名などでレイアウトが崩れることがあります。
ここはAIデータを開き、個別に調整します。
※今回は崩れている例を作っておらず、割愛します
お客様に校正依頼
お客様はイラストレーターソフトを持っていないケースがほとんどですので、今回はPDFを送り、
名刺の情報チェックをしていただきます。
校了後に入稿データを作成します。
次回
校正チェックが完了したデータを、一括で入稿用データにする手順を書きたいと思います!

