Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Tomokatsu-Sakamoto/2c20ae4b6ea821435fa46dd7f8b3a462 to your computer and use it in GitHub Desktop.
Save Tomokatsu-Sakamoto/2c20ae4b6ea821435fa46dd7f8b3a462 to your computer and use it in GitHub Desktop.
'use strict' // 変数の宣言を強制
const THUMB_W = 320; // サムネイル画像の幅
const THUMB_H = 180; // サムネイル画像の高さ
function onOpen() {
Logger.log("[開始] メニュー項目を追加");
SpreadsheetApp.getUi()
.createMenu('スピーカーノート操作')
.addItem('ID の確認', 'getSlideName')
.addSeparator()
.addItem('シートに取得', 'getSpeakerNotesText')
.addItem('スライドへ書き出し', 'setSpeakerNotesText')
.addSeparator()
.addItem('シートのクリア', 'clearSheet')
.addToUi();
Logger.log("[終了] メニュー項目を追加");
}
/**
* 指定された ID から、スライドの名前を取得する。
*/
function getSlideName() {
const sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
const slideID = sheet.getRange('B1').getValue(); // 対象となるスライドの ID
const slide = SlidesApp.openById(slideID); // 対象となるスライドを開く
sheet.getRange('C1').setValue(slide.getName()); // セル C1 にスライドの名前を設定
}
/**
* シートをクリアする ※ただし、A1:B1 は除く
*/
function clearSheet() {
const sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
let maxCol = sheet.getMaxColumns();
let maxRow = sheet.getLastRow();
sheet.getRange('C1').clearContent(); // セル C1 をクリア
if (maxRow > 1) {
sheet.setRowHeights(2, maxRow - 1, 21); // サムネイル画像の高さはデフォルト値の 21
sheet.setColumnWidth(3, THUMB_W); // サムネイル画像の 幅 は 320 のまま
// 現在のシートの内容を、2行目以降クリア
let range = sheet.getRange(2, 1, maxRow - 1, maxCol);
console.info('(' + maxCol + ',' + maxRow + ') ' + range.getA1Notation());
range.clearContent();
}
}
/**
* スライドの内容からスピーカーノートを抽出して、スプレッドシートに書き出す。
*/
function getSpeakerNotesText() {
const sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
const slideID = sheet.getRange('B1').getValue(); // 対象となるスライドの ID
const slide = SlidesApp.openById(slideID); // 対象となるスライドを開く
let targetFolderId = searchFolder(slide); // 出力先のフォルダをチェックする
const targetFolder = DriveApp.getFolderById(targetFolderId); // 新しいファイルを保存するフォルダ
console.info('targetFolderId : ' + targetFolderId);
clearSheet(); // 一旦、シートをクリアする
getSlideName(); // スライドのタイトルを取得
// スライドの内容からスピーカーノートを抽出して、スプレッドシートに書き出す。
let slides = slide.getSlides(); // スライドをすべて取得
for (let i = 0; i < slides.length; i++) { // スライドの枚数分だけくり返す
// スライドのサムネイル画像を生成する
let res = Slides.Presentations.Pages.getThumbnail(slideID, slides[i].getObjectId());
// 画像データを取得
// https://developers.google.com/slides/api/reference/rest/v1/presentations.pages/getThumbnail
let fileName = '#' + String(i + 1).padStart(3, '0') + ' ' + slide.getName(); // ファイル名
let response = UrlFetchApp.fetch(res.contentUrl); // 生成したサムネイル画像をダウンロード
let fileBlob = response.getBlob().setName(fileName);
// 取得した画像をGoogle Driveにアップロード
let file = DriveApp.createFile(fileBlob); // 画像ファイルをマイドライブに作成
targetFolder.addFile(file); // 作成したファイルを、指定のフォルダに移動
// IMAGE 関数のためにアクセス権を設定
// https://developers.google.com/apps-script/reference/drive/file#setsharingaccesstype,-permissiontype
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
sheet.appendRow( // 取得した内容で行を追加
[
i + 1, // スライド番号
slides[i].getNotesPage() // ノートページを取得
.getSpeakerNotesShape() // スピーカーノートを含む形状を取得
.getText() // テキスト コンテンツを取得
.asString(), // 生のテキスト
// IMAGE 関数でページのサムネイルを生成
`=IMAGE("https://drive.google.com/uc?export=download&id=${file.getId()}",4,${THUMB_H},${THUMB_W})`,
]
);
}
sheet.setRowHeights(2, sheet.getLastRow() - 1, THUMB_H); // サムネイル画像の高さは 180
sheet.setColumnWidth(3, THUMB_W); // サムネイル画像の 幅 は 320
sheet.getRange(2, 1, sheet.getLastRow() - 1, 3).setVerticalAlignment('top'); // 垂直方向は「上」
}
/**
* スプレッドシートの内容からスライドのスピーカーノートを更新する。
*/
function setSpeakerNotesText() {
const sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
const slideID = sheet.getRange('B1').getValue(); // 対象となるスライドの ID
const slide = SlidesApp.openById(slideID); // 対象となるスライドを開く
// スプレッドシートの内容からスライドのスピーカーノートを更新する。
let slides = slide.getSlides(); // スライドをすべて取得
for (let i = 0; i < slides.length; i++) { // スライドの枚数分だけくり返す
slides[i].getNotesPage() // ノートページを取得
.getSpeakerNotesShape() // スピーカーノートを含む形状を取得
.getText() // テキスト コンテンツを取得
.setText( // テキストを設定する
sheet.getRange(i + 2, 2).getValue() // シートの該当セルの内容
);
}
}
/*****************************************************************************
* 指定されたフォルダが存在しているのかをチェック
*  1. 出力先となるフォルダが存在しているかをチェックし、存在していなければ
*  作成する
*
* @param {Spreadsheet} ss 処理対象となるスプレッドシート
* @return {String} 出力先のフォルダの ID
*/
function searchFolder(ss) {
//////////////////////////////////////////////////////////////////////////////
// 1. 出力先となるフォルダが存在しているかをチェックし、存在していなければ作成する
const fileName = ss.getName(); // ファイル名を取得する
const fileId = ss.getId(); // スプレッドシートのファイル ID を取得
let targetFolder; // 戻り値となるチェック対象のフォルダ ID
// スプレッドシートのファイル ID から保存されているフォルダの ID を取得
let parentFolder = DriveApp.getFileById(fileId).getParents();
let folderId = parentFolder.next().getId();
// スプレッドシートの名前でフォルダが存在しているのかを確認
const folderIterator = DriveApp.getFolderById(folderId).getFoldersByName(fileName);
if (folderIterator.hasNext()) {
// 存在する場合
targetFolder = folderIterator.next();
}
else {
// 存在しない場合 → フォルダを作成する
Logger.log("フォルダを作成する:" + fileName);
targetFolder = DriveApp.getFolderById(folderId).createFolder(fileName);
}
return targetFolder.getId();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment