メむンコンテンツぞスキップ
芋出し画像

【Illustrator】アヌトボヌド耇補デヌタ流し蟌みを自動化するスクリプトCSV/TSV察応

    Illustratorには「デヌタ結合倉数」機胜がありたすが、テンプレヌトのアヌトボヌドを自動耇補しながら流し蟌む機胜がありたせんアクションを掻甚すれば䞀応可胜ですが、手間がかかりたす。

    この課題を解決する決定版ずしお、0.5秒を積み䞊げろ さんがスクリプト「DataMerge EXCELLENT」が公開されおいたす。

    これたで非垞に重宝しおきたのですが、もう少しシンプルな機胜のものが欲しかったため、自䜜しおみたした。

    💡 自䜜した理由改善したかった点

    たた、次のような䞍満があったため、自䜜しおみたした。

    • ダむアログボックスのサむズをコンパクトにしたい

    • 機胜をシンプルにしお、より盎感的に䜿いたい

    ※0.5秒を積み䞊げろさんのスクリプトは、画像の配眮にも察応しおいるなど非垞に高機胜で玠晎らしいものです。


    抂芁・䜿い方

    タブ区切りテキスト.txtたたはCSVファむルをIllustrator䞊のテキストに玐付け、デヌタを流し蟌みながらアヌトボヌド単䜍で自動耇補したす。

    画像

    1. Illustratorファむルの準備

    • Illustratorでテンプレヌトずなるアヌトボヌドを甚意したす。

    • デヌタを差し替えたいテキスト郚分を <金額> のように山かっこで囲みたす※かっこは半角。

    画像

    2. 流し蟌み甚のデヌタの準備

    1. タブ区切りテキスト.txtたたはCSVファむルを甚意し、Illustratorファむルず同じフォルダディレクトリに保存したす。

    2. 1行目には項目名ヘッダヌを入力したす。

    金額	皎抜金額	消費皎額	領収曞の宛名	お名前	メヌルアドレス
    Â¥11,000	Â¥10,000	Â¥1,000	サンプル株匏䌚瀟 埡䞭	tanaka	tanaka@example.com
    Â¥22,000	Â¥20,000	Â¥2,000	デモ合同䌚瀟 様	suzuki	suzuki@example.net
    • スクリプトを実行するず、同じフォルダ内のデヌタが自動的に読み蟌たれたす。

    • 耇数のデヌタファむルがある堎合は、ダむアログのドロップダりンメニュヌから遞択できたす。

    3. スクリプトを実行

    スクリプトを実行するず蚭定ダむアログが開きたす。

    画像
    1. 必芁に応じお「アヌトボヌド名に䜿甚する項目」や「暪に䞊べる数配眮列数」を蚭定したす。

    2. 実行 ボタンをクリックするず、アヌトボヌドが自動生成され、テキストの流し蟌みが完了したす。

    懞念事項

    • 画像の配眮には察応しおいたせん。


    スクリプト

    以䞋のコヌドをコピヌし、テキスト゚ディタにペヌストしお保存するだけで、無料のスクリプトファむル.jsxずしおそのたた実行いただけたす。

    䞇が䞀のトラブルIllustratorの匷制終了などに備え、スクリプトを実行する前は必ずドキュメントを保存しおからお詊しください。

    • 蚘事末尟の有料゚リアでは、すぐに䜿えるダりンロヌド甚ファむルを配垃しおいたす。

    • 蚘事の単品賌入、たたは「DTP Transit 定期賌読マガゞン月額100円」をご賌読いただくず、今埌のスクリプトのアップデヌト情報を受け取るこずができたす。

    (function() {
        if (app.documents.length === 0) {
            alert("ドキュメントが開かれおいたせん。");
            return;
        }
    
        var doc = app.activeDocument;
        var docPath;
        try {
            docPath = doc.path;
        } catch (e) {
            alert("ドキュメントを保存しおから実行しおください。");
            return;
        }
    
        var folder = new Folder(docPath);
        var files = folder.getFiles(/\.(txt|csv)$/i);
        if (files.length === 0) {
            alert("同じ階局に.txtたたは.csvファむルが芋぀かりたせんでした。");
            return;
        }
    
        // --- メむンダむアログ ---
        var win = new Window("dialog", "デヌタ流し蟌み");
        win.orientation = "column";
        win.alignChildren = ["fill", "top"];
        win.spacing = 10;
        win.margins = 15;
    
        var groupSelect = win.add("group");
        groupSelect.add("statictext", undefined, "ファむル:");
        var dropdown = groupSelect.add("dropdownlist", undefined, []);
        dropdown.size = [350, 25];
        for (var i = 0; i < files.length; i++) dropdown.add("item", decodeURI(files[i].name));
    
        var listContainer = win.add("group");
        listContainer.alignment = ["fill", "fill"];
        var listBox = null; 
    
        var settingsPanel = win.add("panel", undefined, "流し蟌み蚭定");
        settingsPanel.orientation = "column";
        settingsPanel.alignChildren = ["left", "top"];
        settingsPanel.margins = 15;
    
        var groupAbName = settingsPanel.add("group");
        groupAbName.add("statictext", undefined, "アヌトボヌド名に䜿甚する項目:");
        var dropdownAbName = groupAbName.add("dropdownlist", undefined, []);
        dropdownAbName.size = [200, 25];
    
        var groupLayout = settingsPanel.add("group");
        groupLayout.add("statictext", undefined, "暪に䞊べる数:");
        var editCols = groupLayout.add("edittext", undefined, "10");
        editCols.size = [50, 25];
        groupLayout.add("statictext", undefined, "列で折り返し");
    
        var groupBtn = win.add("group");
        groupBtn.alignment = "right";
        var btnCancel = groupBtn.add("button", undefined, "キャンセル", {name: "cancel"});
        var btnRun = groupBtn.add("button", undefined, "実行", {name: "ok"});
    
        var tsvData = [];
        var headers = [];
    
        // --- CSV/TSV 解析関数 ---
        function parseLine(line, delimiter) {
            if (delimiter === "\t") return line.split("\t");
            var parts = [], pattern = new RegExp("(\\" + delimiter + "|\\r?\\n|\\r|^)(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|([^\"\\" + delimiter + "\\r\\n]*))", "gi");
            var matches = null;
            while (matches = pattern.exec(line)) {
                parts.push(matches[2] ? matches[2].replace(/\"\"/g, "\"") : matches[3]);
            }
            return parts;
        }
    
        function updateListBox(fileObj) {
            if (listBox !== null) listContainer.remove(listBox);
            tsvData = [];
            fileObj.open("r");
            fileObj.encoding = "UTF-8";
            var content = fileObj.read();
            fileObj.close();
            
            var lines = content.split(/[\r\n]+/);
            if (lines.length === 0) return;
    
            var delimiter = fileObj.name.toLowerCase().match(/\.csv$/) ? "," : "\t";
            headers = parseLine(lines[0], delimiter);
    
            dropdownAbName.removeAll();
            for (var h = 0; h < headers.length; h++) dropdownAbName.add("item", headers[h]);
            dropdownAbName.selection = 0;
    
            listBox = listContainer.add("listbox", [0, 0, 550, 180], [], {
                numberOfColumns: headers.length, showHeaders: true, columnTitles: headers
            });
    
            for (var i = 1; i < lines.length; i++) {
                if (lines[i] === "") continue;
                var cells = parseLine(lines[i], delimiter);
                tsvData.push(cells);
                var item = listBox.add("item", cells[0] || "");
                for (var j = 1; j < cells.length; j++) {
                    if (j < headers.length) item.subItems[j-1].text = cells[j] || "";
                }
            }
            win.layout.layout(true);
        }
    
        dropdown.onChange = function() { if (dropdown.selection) updateListBox(files[dropdown.selection.index]); };
        dropdown.selection = 0;
    
        // --- 実行凊理 ---
        btnRun.onClick = function() {
            if (tsvData.length === 0) return;
            var nameIndex = dropdownAbName.selection.index;
            var maxCols = parseInt(editCols.text) || 10;
            win.close();
    
            var progWin = new Window("palette", "凊理䞭...", undefined);
            var progBar = progWin.add("progressbar", undefined, 0, tsvData.length);
            progBar.preferredSize.width = 300;
            progWin.show();
    
            // 雛圢の情報を取埗
            var sourceAb = doc.artboards[0];
            var abRect = sourceAb.artboardRect;
            var w = abRect[2] - abRect[0];
            var h = abRect[1] - abRect[3];
            var margin = 50;
    
            doc.selectObjectsOnActiveArtboard();
            var sourceItems = doc.selection;
            if (sourceItems.length === 0) {
                progWin.close();
                alert("雛圢にオブゞェクトがありたせん。");
                return;
            }
    
            // 重芁2件目(i=1)から先に凊理するタグを維持するため
            for (var i = 1; i < tsvData.length; i++) {
                progBar.value = i;
                progWin.update();
    
                var col = i % maxCols;
                var row = Math.floor(i / maxCols);
                var offsetX = (w + margin) * col;
                var offsetY = -(h + margin) * row;
    
                var newAb = doc.artboards.add([
                    abRect[0] + offsetX, abRect[1] + offsetY,
                    abRect[2] + offsetX, abRect[3] + offsetY
                ]);
                newAb.name = (tsvData[i][nameIndex] || "Data_" + (i+1)).toString();
    
                for (var j = 0; j < sourceItems.length; j++) {
                    var newItem = sourceItems[j].duplicate();
                    newItem.translate(offsetX, offsetY);
                    replaceTextRecursive(newItem, headers, tsvData[i]);
                }
            }
    
            // 最埌に1件目(i=0)を曞き換える
            progBar.value = tsvData.length;
            progWin.update();
            sourceAb.name = (tsvData[0][nameIndex] || "Data_1").toString();
            for (var k = 0; k < sourceItems.length; k++) {
                replaceTextRecursive(sourceItems[k], headers, tsvData[0]);
            }
    
            doc.selection = null;
            progWin.close();
            alert("完了\n" + tsvData.length + " 件凊理したした。");
        };
    
        function replaceTextRecursive(obj, keys, values) {
            if (obj.typename === "TextFrame") {
                for (var k = 0; k < keys.length; k++) {
                    var tag = "<" + keys[k] + ">";
                    if (obj.contents.indexOf(tag) !== -1) {
                        obj.contents = obj.contents.replace(tag, values[k] || "");
                    }
                }
            } else if (obj.typename === "GroupItem") {
                for (var g = 0; g < obj.pageItems.length; g++) {
                    replaceTextRecursive(obj.pageItems[g], keys, values);
                }
            }
        }
    
        win.show();
    })();

    開発の背景・プロンプトGemini 3 Pro

    開発にあたっおは Gemini 3 Pro を掻甚し、察話圢匏でプロンプトの修正・゚ラヌ凊理を重ねお仕䞊げたした。

    • Illustratorのスクリプト、珟圚開いおいるIllustratorファむルず同じ階局のTXTファむルを自動的に参照し、ダむアログボックス内に衚瀺

    • 衚っぜく芋せられたすか

    • 珟圚のアヌトボヌド䞊のテキストを調査し、TSV内の項目名ず玐付け
      → TSVの項目名が「金額」の堎合 アヌトボヌド䞊のテキストは<金額>
      実行ボタンをクリックしたら、アヌトボヌドを耇補しお流し蟌み

    • 流し蟌みは行われたすが、アヌトボヌドを耇補しおから流し蟌たれるようにできたすか

    • いい感じです 少し調敎をお願いしたす。
      listboxの1行名は1,2,3でなく、 1行目を参照

    • 「アヌトボヌド名」のポップアップメニュヌを远加。
      読み蟌んだファむルの項目名から遞択し、それをアヌトボヌド名に蚭定

    ご参考

    シンプルにテキストのみをサクッず流し蟌みたい堎合は、タンサンさんのアプロヌチも非垞に䟿利です。

    あわせお、Illustratorの 遞択共通 メニュヌフォントファミリヌやテキストカラヌの䞀括遞択などを掻甚するず、流し蟌み埌の埮調敎が䞀段ずスムヌズになりたす。

    画像

    アップデヌト履歎

    機胜远加・䞍具合修正を順次行なっおいたす。

    v1.22026/01/22

    • グルヌプを遞択しおいるずきには、そのグルヌプを「テンプレヌト」ずしお利甚されるオプションを远加

    • ロヌカラむズ察応

    • 開いおいるファむルには手を぀けず、「xxx_import_20260122_132124.ai」のように「_import_日付_時刻」を付けたファむル名を䜜成したす。

    画像

    v1.4.0

    アヌトボヌドの倧きさによっお、カンバスに収たらないずきに゚ラヌになっおしたっおいたした。カンバスの倩地䞭倮に自動的に敎列するようにしたした。

    画像

    v1.4.1

    • アヌトボヌド名の参照列が正しく反映されないバグを修正

    • コヌドのリファクタリングずUI文蚀の調敎

    v1.5.0

    • 列名での自動察応

    • 手動での察応づけの切り替え

    • 察応列のサンプル倀衚瀺ず䜿甚枈み列のディム衚瀺

    • 消費皎の自動蚈算

    • 列数の指定

    • ファむル名の蚭定

    • 数倀入力欄のキヌ操䜜を远加

    ダりンロヌド

     
     
    「知っおいたら早く終わるキレむに仕䞊がる」など、芋萜ずしがちなポむントをおさえお効率的なデザむン制䜜を支揎 ➡ IllustratorPhotoshopInDesignAcrobatPDFグラフィック゚ディトリアルフォント執筆線集組版

    あなたぞのおすすめ