【GAS、Google Spreadsheet】ドライブにある画像をセルに表示しまくるツール

1334 語
7 分
【GAS、Google Spreadsheet】ドライブにある画像をセルに表示しまくるツール

はじまり#

リサちゃん avatar
リサちゃん
あけおメントスコーラ~
135ml avatar
135ml
ことよロンドンブーツ1号2号3号625901号~
リサちゃん avatar
リサちゃん
さあ、こんなしょうもない挨拶をしたからには、何か記事にするんだろうね?
135ml avatar
135ml
モチロンですとも! 今回は、ドライブにある画像ファイルGoogleスプレッドシートに表示しまくっちゃおうという題目です。Googleスプシで管理しているリストの見栄えを良くするために参考にしてくだせえ。

ツールの概要#

このツールを実行すると、Googleドライブにある画像のファイル名と同じ名前のサイトと対応する箇所にIMAGE関数を入力しまくってくれます。

ソース#

function listFormated(listReadFromGss) {
var listFormated = [];
for (let j = 0; j < listReadFromGss.length; j++) {
// "if" statement in one liner. If '', nothing to do.
listReadFromGss[j][0]=='' ? true : listFormated.push(listReadFromGss[j][0]);
}
return listFormated
}
/**
* Get number of record in Google Spreadsheet.
*
* @param {"bookmarkSites"} sheetName - Name of sheet that you wanna know number of record.
* @return Number of record
* @customfunction
*/
function get_row_to_read_actual_in_GSS(sheetName) {
// declare list for warning message.
var warningMessage = 'Warning: Number of row passing over \"row_to_read\". Tweak me.';
var errorMessage = 'RowIndexOutOfBoundsError: Number of row reached \"row_to_read\". Tweak me.';
// declare variables for row and column index.
var row_to_read = 201;
var row_to_read_actual;
// declare list.
var idList;
// get sheet.
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName);
// memorize number of row to read
console.time(`SELECT TOP${row_to_read - 1} id FROM \'${sheetName}\'`);
idList = sheet.getRange(2, column_for_siteBookmark_of_id, row_to_read - 1, 1).getValues();
console.timeEnd(`SELECT TOP${row_to_read - 1} id FROM \'${sheetName}\'`);
idList_formated = listFormated(idList);
// warning message. If condition is false, nothing to do.
row_to_read_actual = Number(idList_formated.reduce((a,b)=>Math.max(a,b)));
row_to_read - row_to_read_actual <= 2 ? console.warn(warningMessage) : false;
if(row_to_read_actual >= row_to_read - 1){
console.error(errorMessage);
return 0;
}
return row_to_read_actual;
}
/**
* Get list to set image onto Google Spreadsheet.
*
* @return [[number], [string]] - recordId and fileFullname
* @customfunction
*/
function getListToSetImage() {
// declare variables for prepare.
var ss,
sheet;
var bookmarkList;
ss = SpreadsheetApp.getActive();
sheet = ss.getSheetByName(sheetName2nd);
var row_to_read_actual = get_row_to_read_actual_in_GSS(sheetName2nd);
if(row_to_read_actual == 0){
console.error(errorMessageList[0]);
return false;
}
// Get files' name and fullname to JSON format.
var folder = DriveApp.getFolderById(iconFolderId),
files = folder.getFiles(),
file;
var fileNameList = [],
fileFullNameList = [],
fileNameDict = {},
iconInsertingRecordList = [];
while(files.hasNext()) {
file = files.next();
fileNameList.push(file.getName().match(/([^/]*)\./)[1]);
fileFullNameList.push(file.getName())
}
fileNameDict['name'] = fileNameList;
fileNameDict['fullName'] = fileFullNameList;
// Get siteName list from GSS and extract record that fileName and siteName are same.
bookmarkList = sheet.getRange(row_for_siteBookmark_of_firstRecord, column_for_siteBookmark_of_id, row_to_read_actual, column_for_siteBookmark_of_icon).getValues();
bookmarkList.forEach(function(record) {
if (record[column_for_siteBookmark_of_icon - 1] == '') {
for (let i = 0; i < fileNameDict['name'].length; i++){
if (fileNameDict['name'][i] == record[column_for_siteBookmark_of_siteName - 1]) {
iconInsertingRecordList.push([record[column_for_siteBookmark_of_id - 1], fileNameDict['fullName'][i]]);
break;
}
}
}else{
// nothing to do.
}
});
return iconInsertingRecordList;
}
function serializeArray(targetArray){
var onlyStringArray = [];
targetArray.forEach(item => {
onlyStringArray.push(`[${String(item)}]`);
});
var serializedArray = onlyStringArray.join(',');
return serializedArray;
}
function setImageFromList(listToSetImage) {
// declare variables.
var file;
var iconUrl,
formattedUrl;
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName2nd);
console.info(`INFO: listToSetImage is${serializeArray(listToSetImage)}`);
// In this case, not in-cell image but OverGridImage...
// var file = DriveApp.getFolderById(iconFolderId).getFilesByName('note.png').next();
// var fileBlob = file.getBlob();
// var insertedImage = sheet.insertImage(fileBlob, column_for_siteBookmark_of_icon, 4);
// insertedImage.setAnchorCell(sheet.getRange(4, column_for_siteBookmark_of_icon));
// execute this code to set file permission and set in-cell image.
listToSetImage.forEach(record => {
file = DriveApp.getFolderById(iconFolderId).getFilesByName(record[1]).next();
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
iconUrl = file.getUrl();
formattedUrl = iconUrl.replace('file/d/', 'uc?export=download&id=').replace('/view?usp=drivesdk', '')
sheet.getRange(record[0] + row_for_siteBookmark_of_firstRecord - 2, column_for_siteBookmark_of_icon).setFormula(`=IMAGE(\"${formattedUrl}\")`)
});
}
function setImageFromGoogleDrive() {
var listToSetImage = getListToSetImage();
console.time(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
setImageFromList(listToSetImage);
console.timeEnd(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
}

ソースの解説#

以下、ソースの解説になります。

関数起動#

まず、setImageFromGoogleDrive()をキックします。

function setImageFromGoogleDrive() {
var listToSetImage = getListToSetImage();
console.time(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
setImageFromList(listToSetImage);
console.timeEnd(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
}

getListToSetImage()#

まず、変数を宣言して、この部分ではget_row_to_read_actual_in_GSS()を利用して、実際にシート内にレコードが何件あるのかを数えて、処理対象の行数を取得します。

var row_to_read_actual = get_row_to_read_actual_in_GSS(sheetName2nd);
if(row_to_read_actual == 0){
console.error(errorMessageList[0]);
return false;
}

ファイル名の拡張子を除いた分を取得する#

そして、次にアイコンにする画像ファイルが入っているフォルダから、画像ファイルを全て取得してファイル名も取得します。以下で、拡張子が除かれたファイル名が取得できます。

fileNameList.push(file.getName().match(/([^/]*)\./)[1]);

アイコンを追加する行を取得する#

アイコン用の画像ファイルがあり、かつアイコンがまだ追加されていない行を総当たりさせて、両方とも満たす行をiconInsertingRecordListの配列にpushします。

bookmarkList.forEach(function(record) {
if (record[column_for_siteBookmark_of_icon - 1] == '') {
for (let i = 0; i < fileNameDict['name'].length; i++){
if (fileNameDict['name'][i] == record[column_for_siteBookmark_of_siteName - 1]) {
iconInsertingRecordList.push([record[column_for_siteBookmark_of_id - 1], fileNameDict['fullName'][i]]);
break;
}
}
}else{
// nothing to do.
}
});

ログも取る#

次に、先程取得した行の情報を元にアイコンを表示するため、スプシにIMAGE関数を入れる処理になります。

console.time()console.timeEnd()で挟まれている処理にどれだけ時間が掛かったかを計測します。この処理では、おおよそIMAGE関数を入れる処理で時間を食いがちです。(追加するアイコンが3つある場合は5秒位掛かります。)

function setImageFromGoogleDrive() {
var listToSetImage = getListToSetImage();
console.time(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
setImageFromList(listToSetImage);
console.timeEnd(`UPDATE \'${sheetName2nd}\' SET favicon = ∀image WHERE favicon = ''`);
}

IMAGE関数を入れる#

ここが実際に入れている処理になります。 まず、setSharing()で、画像ファイルを共有ファイルにする必要があります。共有ファイルにしないとIMAGE関数で表示されません。

次に、replace()でクエリパラメータや参照モードを示す/viewの文字列を消して、画像ファイルの純粋なURLを取得する必要があります。

これらの前処理をして、やっとIMAGE関数でセル内に画像を表示させることが出来ます。このsetFormula()に時間が掛かります・・・!

listToSetImage.forEach(record => {
file = DriveApp.getFolderById(iconFolderId).getFilesByName(record[1]).next();
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
iconUrl = file.getUrl();
formattedUrl = iconUrl.replace('file/d/', 'uc?export=download&id=').replace('/view?usp=drivesdk', '')
sheet.getRange(record[0] + row_for_siteBookmark_of_firstRecord - 2, column_for_siteBookmark_of_icon).setFormula(`=IMAGE(\"${formattedUrl}\")`)
});

上記のようにIMAGE関数をsetFormulaする方法ではなく、関数として返り値(Blob的な)を画像にするという考えもあったのですが、以下の理由でやめておきました。

  1. SpreadsheetApp APIで画像をBlobを使って表示する方法だとOverGridImageの形式しか扱えないっぽい。
  2. セルからはみ出たデカい画像が貼られてしまう。
  3. カスタム関数を全ての行に適用すると、スプシの表示が遅くなりそう。

完了#

はい! Googleドライブにある画像をアイコンに出来ました!

おしまい#

135ml avatar
135ml
うおーし、よっしゃあー、だいぶ見栄えが良くなったぜい。
リサちゃん avatar
リサちゃん
っぽくなったなぁ

以上になります!

記事を共有

この記事が役に立ったなら、ぜひ他の人と共有してください!

【GAS、Google Spreadsheet】ドライブにある画像をセルに表示しまくるツール
https://endorphinbath.com/posts/gas-display-image-in-drive/
著者
kinkinbeer135ml
公開日
2022-01-01
ライセンス
CC BY-NC-SA 4.0
関連記事 スマート
1
【GAS、Google Spreadsheet】ブログに使用した画像をGoogleドライブで管理するために書いたスクリプト
Code 僕は、既に公開した記事で使用したファイルをGoogleドライブの所定のフォルダに保存しています。その画像を完了済みのフォルダに定期的に移動してくれるスクリプトを作りました。
2
【GAS、Google Spreadsheet】Googleドライブのフォルダに有るファイルを一覧で取得するスクリプトです
Code GoogleDriveの指定のフォルダにあるファイルを一覧で取得します。Googleドライブを整理したい時に役立つツールになるかと思います。
3
【GAS、Google Spreadsheet】Googleドライブのルートフォルダに有るフォルダを一覧で取得するスクリプトです
Code GoogleDriveのルートフォルダにあるフォルダを一覧で取得します。Googleドライブを整理したい時に役立つツールになるかと思います。
4
【GAS、Google Spreadsheet】Googleドライブ内の指定したフォルダに所定のファイルをコピーするスクリプトです
Code GoogleDriveの指定のフォルダにファイルをコピーするツールを作りました。何かWebの記事をGoogleドキュメントにクリップしたり、指定のフォルダにメモ書きやシートを作成したい場合に役立つかと思います。
5
【GAS、Google Spreadsheet】Googleドライブ内の指定したファイルをそれぞれ好みの名前に一気にリネームするスクリプトです
Code GoogleDriveの指定のファイルを一括でリネームできるツールを作りました。既に沢山作ってしまったファイルの命名規則を変えたいときなどにご活用下さい。
ランダム記事 ランダム
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次