LoginSignup
0
1

More than 1 year has passed since last update.

InDesign JavaScript Excelの内容を配置(画像位置に)

Last updated at Posted at 2022-06-18

Excelの内容を配置(画像位置に)するスクリプトは、これで良いのかな・・・?

/*
このスクリプトを利用して起こった不具合の責任は取れません。
ご了承下さい。

更新 2022/06/24
*/

// アプリ指定
#target "indesign";

// スクリプト名
const scriptName = "Excelの内容を配置(画像位置に)";

//スクリプトの動作指定(一つのアンドゥ履歴にする、及び、アンドゥ名)
app.doScript(function(){

    // ダイアログ
    var dialogueFlg = confirm("Excelの内容を元に、同名の画像の位置にExcelの内容を入れたテキストフレームを配置します。" + "\r"
    + "\r"
    + "Excelの内容を入れるテキストフレームの雛形を複製するので、オブジェクトスタイル、段落スタイル、レイヤー等が保持されます。" + "\r"
    + "Excelの1列目はテキストフレームの1段目に、2列目は2段目に入ります。列が7つの場合は段落は7つ必要です。" + "\r"
    + "\r"
    + "Excelの内容を入れる雛形のテキストフレームを選択して、スクリプトを実行して下さい。"
    , "", scriptName);

    // Noの場合
    if(dialogueFlg == false){

        // 終了
        exit();
    }

    // excelの読み込み設定
    app.excelImportPreferences.tableFormatting = TableFormattingOptions.EXCEL_UNFORMATTED_TABLE;
    
    // アンフォーマットテーブルが選ばれていない場合
    if(app.excelImportPreferences.tableFormatting != TableFormattingOptions.EXCEL_UNFORMATTED_TABLE){
        
        // 警告
        alert("scriptでexcelを読み込む為、(excel読み込みオプションでアンフォーマットテーブルを選び)一度配置して下さい。");
        
        // 終了
        exit();
    }
    
    // 結果数
    var resultNumber = 0;
    
    // 選択が有り、かつ、TextFrameの場合
    if(app.activeDocument.selection.length > 0 && app.activeDocument.selection[0].constructor.name == "TextFrame"){
            
            // 雛形のテキストフレーム
            const templateTextFrame = app.activeDocument.selection[0];

    // 以外の場合
    }else{
            
        // 警告
        alert("雛形のテキストフレームを選択して下さい。");
            
        // 終了
        exit();
    }

    // ファイルオープンダイアログ
    var excelFile = File.openDialog("Excelファイルを選択してください","*.xlsx",false);

    // 開けなかった場合
    if(!excelFile){

        // 終了
        exit();
    }

    // 最小化
    app.activeWindow.minimize();

    // 進行状況用パレット
    var palette = new Window("palette");
    palette.text = "進行状況";
    palette.orientation = "column";
    palette.alignChildren = ["left","top"]; 
    palette.spacing = 10; 
    palette.margins = 16; 

    var group1 = palette.add("group"); 
    group1.orientation = "row"; 
    group1.alignChildren = ["left","center"]; 
    group1.spacing = 10; 
    group1.margins = 0; 

    group1.add("statictext").text = "Excel:"; 

    var nowRowNumberText = group1.add("statictext");
    nowRowNumberText.text = "-------";

    group1.add("statictext").text = "/"; 

    var excelRowCellFirstItemArrayNumber = group1.add("statictext");
    excelRowCellFirstItemArrayNumber.text = "-------";

    group1.add("statictext").text = "行目"; 

    var group2 = palette.add("group"); 
    group2.orientation = "row"; 
    group2.alignChildren = ["left","center"]; 
    group2.spacing = 10; 
    group2.margins = 0; 

    group2.add("statictext").text = "配置数:"; 

    var resultNumberText = group2.add("statictext"); 
    resultNumberText.text = "-------";

    // 表示
    palette.show();

    // エクセルファイル配置用のテキストフレーム追加
    const excelPlaceTextFrame = app.activeDocument.pages.firstItem().textFrames.add();
    
    // 大きさの調整
    excelPlaceTextFrame.geometricBounds = app.activeDocument.pages.firstItem().bounds;

    // 配置
    excelPlaceTextFrame.place(excelFile);
    
    // 前のテキストフレーム
    var previousTargetPreviousTextFrame = excelPlaceTextFrame;
    
    // 次のテキストフレーム
    var nextTargetTextFrame;
    
    // オーバーフロウの場合   
    while(previousTargetPreviousTextFrame.overflows == true){

        // テキストフレーム追加
        nextTargetTextFrame = app.activeDocument.pages.firstItem().textFrames.add();

        // 大きさの調整
        nextTargetTextFrame.geometricBounds = app.activeDocument.pages.firstItem().bounds;
        
        // 連結
        previousTargetPreviousTextFrame.nextTextFrame = nextTargetTextFrame;
        
        // 前のテキストフレームに入れる
        previousTargetPreviousTextFrame = nextTargetTextFrame;
    }

    // excelの最初の列のセルの情報配列
    const excelRowCellFirstItemArray = excelPlaceTextFrame.tables.firstItem().rows.everyItem().cells.firstItem().contents;
    
    // 行の数
    excelRowCellFirstItemArrayNumber.text = excelRowCellFirstItemArray.length;
    
    // リンクファイル名配列
    var linkFileNameArray = [];
    
    // リンクファイルの数だけ繰り返す
    for(var i = 0; app.activeDocument.links.count() > i; i++){
            
        // リンクファイル名収集
        linkFileNameArray.push(app.activeDocument.links.item(i).name.match(/.+(?=\.[a-z]+)/));
    }

    // リンクファイル名連結文
    const linkFileNameString = linkFileNameArray.join(",");
    
    // 正規表現オブジェクト
    var regExpObject;
    
    // 対象の画像フレーム
    var targetImageFrame;

    // 複製されたテキストフレーム
    var duplicateTextFrame;
    
    // 範囲の終わりの数値
    var itemByRangeToNumber = 0;
    
    // 移動先
    var destination;
    
    // 繰り返し数
    var repeatNumber;
    
    // 元の定規の単位
    const myRulerOrigin = app.activeDocument.viewPreferences.rulerOrigin;
    
    // 定規の単位をグリッドに(moveメソッドに影響)
    app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
    
    // 行の数だけ繰り返す
    for(var i = 0; excelRowCellFirstItemArray.length > i; i++){
        
        // 現在の行数表示用
        nowRowNumberText.text = i + 1; 

        // 検索文字
        regExpObject = new RegExp(excelRowCellFirstItemArray[i]);

        // 検索された場合
        if(regExpObject.test(linkFileNameString)){
            
            // リンクファイル名の数だけ繰り返す
            for(var j = 0; linkFileNameArray.length > j; j++){
            
                // エクセルの行の一列目の文字とリンクファイル名が同じ、かつ、エクセルの行の一列目の文字が有る場合
                if(excelRowCellFirstItemArray[i] == linkFileNameArray[j] && excelRowCellFirstItemArray[i] != null){
                        
                    // 対象画像のフレームに入れる
                    targetImageFrame = app.activeDocument.links.item(j).parent.parent;                     

                    // Spreadを取得
                    destination = getSpread(targetImageFrame);
                        
                    // Spreadが取得出来なかった場合
                    if(destination == undefined){
                            
                        // 警告
                        alert("Indesignの不具合(?)の為" + "\r" + (j + 1) + "つ目のリンクのSpreadが取得出来ませんでした。");
                        
                    // 以外の場合
                    }else{
                        
                        // 対象のテキストフレームを複製
                        duplicateTextFrame = templateTextFrame.duplicate();

                        // 対象画像のフレームのページに移動
                        duplicateTextFrame.move(destination);
                            
                        // 対象画像のフレームの座標(visibleBounds[ y1, x1, y2, x2 ])に移動
                        duplicateTextFrame.move([targetImageFrame.visibleBounds[1],targetImageFrame.visibleBounds[0]]);
                            
                        // 最前面へ
                        duplicateTextFrame.bringToFront();
                        
                        // 段落の数が列の数より多い場合
                        if(duplicateTextFrame.paragraphs.count() >= excelPlaceTextFrame.tables.firstItem().columns.count()){
                            
                            // 列の数を入れる
                            repeatNumber = excelPlaceTextFrame.tables.firstItem().columns.count();

                        // 以外の場合
                        }else{
                            
                            // 段落の数を入れる
                            repeatNumber = duplicateTextFrame.paragraphs.count();
                        }
                            
                        // 繰り返しの数だけ逆に繰り返す
                        for(var k = repeatNumber - 1; k >= 0; k--){
                                
                            // 最後の場合
                            if(k == duplicateTextFrame.paragraphs.count() - 1){
                                    
                                // 最後から1つ目を入れる
                                itemByRangeToNumber = -1;
                                    
                            // 以外の場合
                            }else{
                                    
                                // 最後から2つ目を入れる(段落の終わりを残す為)
                                itemByRangeToNumber = -2;
                            }
                                    
                            // 段落にexcelの内容を入れる
                            duplicateTextFrame.paragraphs.item(k).characters.itemByRange(0,itemByRangeToNumber).contents = excelPlaceTextFrame.tables.firstItem().rows.item(i).cells.item(k).contents;
                        }
                    
                        // 結果数を増やす
                        resultNumber++;
                            
                        // 結果数表示用
                        resultNumberText.text = resultNumber;
                    
                        // ガーベージコレクション
                        $.gc();
                    }
                }
            }
        } 
    }

    // エクセルファイル配置用のテキストフレームの親ストーリーが持つテキストフレームの数だけ逆に繰り返す
    for(var i = excelPlaceTextFrame.parentStory.textContainers.length - 1; i >= 0; i--){
        
        // 削除
        excelPlaceTextFrame.parentStory.textContainers[i].remove();
    }
    
    // 定規の単位を戻す
    app.activeDocument.viewPreferences.rulerOrigin = myRulerOrigin;
    
    // 結果
    alert("配置数:" + resultNumber);
    
    // アクティブウィンドウの最大化
    app.activeWindow.maximize();
    
    // ガーベージコレクション
    $.gc();

// スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);

// スプレッド取得関数(オブジェクト)
function getSpread(hierarchyObject){

    // Spread、または、MasterSpreadの場合
    if(hierarchyObject.constructor.name == "Spread" || hierarchyObject.constructor.name == "MasterSpread"){

        // 戻す
        return hierarchyObject;

    // 文字(アンカーオブジェクト)の場合
    }else if(hierarchyObject.constructor.name == "Character"){
        
        // 再帰処理(親のテキストフレーム)
        hierarchyObject = getSpread(hierarchyObject.parentTextFrames[0]);

    // 以外の場合
    }else{
        
        // 再帰処理(一つ上の階層のオブジェクト)
        hierarchyObject = getSpread(hierarchyObject.parent);
    }
    
    // 戻す
    return hierarchyObject;
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1