Help us understand the problem. What is going on with this article?

Google Apps Scrpitでスライドを自動生成

GoogleAnalyticsのスプレッドシート出力機能を使って作られたSpreadsheetや、作業タスクと進捗を記載したSpreadsheetを報告用にスライドに自動生成できないかと思ったらできたので簡単な例を用いて方法をまとめておきます。

Google公式のマニュアル

  1. Google Apps Script - Slides Service
  2. Google Slides API

※基本的に2個目は参考程度で1個目のサイトしか使わなかったです。

ゴール

スプレッドシートの内容を取得してスライドを特定のディレクトリ配下に新規生成する。

前準備

以下のファイルを作ります。

  • スライドの保存先フォルダ
  • テンプレートのスライド
  • 元ネタになるスライド
  • GoogleAppsScript

以下のような感じです。

元ネタとなるスプレッドシートの情報

スプレッドシートの情報は今回以下のようなものを用意します。

テンプレート

スプレッドシートから報告用スライドを自動生成で埋め込む際のテンプレートファイルは以下のようなものを用意します。


スクリプトのプロパティの設定

スクリプトファイルのプロパティを設定していきます。

「ファイル>プロジェクト」で

定義したプロパティは以下の通りです。

  • 保存先のディレクトリのID
  • 引用する元のスプレッドシートのID
  • テンプレートのスライドのID

スクリプトの作成

作成するスクリプトは以下のように分けます。メインの「コード.gs」(デフォルト生成されてるもの)とは別にスライドの1ページごとにスクリプトが用意されるイメージが整理しやすいかなと。

  • コード.gs
  • CreateTitlePage.gs
  • CreateFirstPage.gs

コード.gs

コード.gs
function myFunction() {
  //プロパティの値を取得
  var saveDirId = PropertiesService.getScriptProperties().getProperty("SAVE_DIRECTORY_ID");
  var spreadSheetId = PropertiesService.getScriptProperties().getProperty("TARGET_SPREADSHEET_ID");
  var templateSlideId = PropertiesService.getScriptProperties().getProperty("TEMPLATE_SLIDE_ID");

  //テンプレートのスライドを保存先のフォルダにコピー
  var slideId = copySlideFile(templateSlideId,saveDirId);
  //タイトルページの編集
  createTitlePage(slideId);
  //果物の表とグラフページを編集
  createFirstPage(slideId,spreadSheetId);
}

/***
 * スライドを別のフォルダにコピー
 * @param {String} baseSlideId コピー元のスライドID
 * @param {String} targetDirId 保存先のフォルダのID
 * @return {String} コピー先のスライドID
 */
function copySlideFile(baseSlideId,targetDirId){
  //コピー先フォルダ取得
  var saveDir = DriveApp.getFolderById(targetDirId);

  //コピー元ファイル取得
  var baseFile = DriveApp.getFileById(baseSlideId);

  //ファイルコピー
  var copyFile = baseFile.makeCopy("【作成ファイル】"+getDate(),saveDir);

  //コピー先のファイルのIDを返却
  return copyFile.getId();
}

/***
 * 日付取得
 * @return {String} 日付(yyyy/MM/dd)
 */
function getDate(){
  //今日日付取得
  var today = new Date();
  //フォーマット指定して返却
  return Utilities.formatDate(today, 'Asia/Tokyo', 'yyyy/MM/dd');
}
  • PropertiesService.getScriptProperties().getProperty()で先程定義したプロパティを呼び出しています。
  • copySlideFile(baseSlideId,targetDirId)でテンプレートのスライドファイルを今回作成するスライド用に複製しています。
    • DriveApp.getFolderById(id)でフォルダを取得
    • DriveApp.getFileById(id)でファイルを取得
    • 取得したファイルに対してmakeCopy(name, destination)で名前指定して取得したフォルダに配置

CreateTitlePage.gs

CreateTitlePage.gs
/**
 * タイトルページの作成
 * @param {String} slideId スライドID
 */
function createTitlePage(slideId) {
  //置換対象文字列
  const titileKey = "{TITLE}";
  const subTitleKey = "{SUBTITLE}";

  //タイトルページを取得
  var titleSlide = SlidesApp.openById(slideId).getSlides()[0];

  //タイトルの置換
  titleSlide.replaceAllText(titileKey, "果物の値段");
  //サブタイトルの置換
  titleSlide.replaceAllText(subTitleKey, getDate()+"作成");  
}
  • createTitlePage(slideId)は先程の複製されたスライドのIDを受け取ります
  • SlidesApp.openById(slideId).getSlides()[0];でスライドの0ページ目を取得
  • replaceAllTextでスライドページ内にある文字列の置換を実施

CreateFirstPage.gs

CreateFirstPage.gs
/**
 * 1ページ目の作成
 * @param {String} slideId スライドID
 * @param {String} spreadSheetId スプレッドシートID
 */
function createFirstPage(slideId,spreadSheetId) {
  //タイトル置換対象文字
  const titleKey = "{PAGETITLE}";

  //スプレッドシート取得
  var spreadsheet = SpreadsheetApp.openById(spreadSheetId);
  //ブラウザ利用状況シート取得
  var sheet = spreadsheet.getSheetByName('シート1');
  //スプレッドシートからグラフの一覧取得
  var charts  = sheet.getCharts();

  //1ページ目を取得
  var titleSlide = SlidesApp.openById(slideId).getSlides()[1];

  //タイトルの置換
  titleSlide.replaceAllText(titleKey, "果物の値段の表");

  //スライドに貼るグラフのサイズ指定
  var chartPosition = {left: 365, top: 125};
  var chartSize = {width: 350, height: 250};
  //スライドにグラフ貼り付け
  titleSlide.insertSheetsChart(
    charts[0],
    chartPosition.left,
    chartPosition.top,
    chartSize.width,
    chartSize.height);

  //スプレッドから対象エリア取得
  var range = sheet.getRange('A1:D4');
  var values = range.getDisplayValues();
  var rows = values.length;
  var columns = values[0].length;
  //スプレッドで定義された背景色取得
  var backgrounds = range.getBackgrounds();
  //スプレッドで定義された文字のボールド取得
  var fontWeights = range.getFontWeights();

  //スライドの表を取得
  var table = titleSlide.getPageElements()[1].asTable();

  for(var r = 0; r < rows; r++){
    if(values[r][1] != ""){
      //行の追加
      table.appendRow();
    }
    for(var c = 0; c < columns; c++){
      //セルの取得
      var cell = table.getCell(r,c);
      //値のセット
      cell.getText().setText(values[r][c]);
      //セルにスプレッドの背景色を引用
      cell.getFill().setSolidFill(backgrounds[r][c]);
      //セルにスプレッドの文字太字定義を引用
      cell.getText().getTextStyle().setBold(fontWeights[r][c] == "bold" ? true : false);
    }
  }
  //目安の列を削除
  table.getRow(table.getNumRows()-1).remove();
  table.getRow(table.getNumRows()-1).remove();
}
  • 図の挿入を先に行ってます
    • SpreadsheetApp.openById(id)でスプレッドシートを取得
    • getSheetByName(name)でシートを指定
    • getCharts()でシート内にある図を取得
    • 取得した図をinsertSheetsChart(sourceChart, left, top, width, height)で位置指定してスライドへ貼り付け
  • 表の挿入
    • getPageElements()[1].asTable()でスライドに目安で配置していた表を取得
    • appendRow()で行を追加
    • getCell(rowIndex, columnIndex)で表の位置指定して取得
    • getText().setText(text)で値をセット
    • remove()で目安用の列は削除

※スプレッドシートの値取得などは他の方がよくまとめてるものがあるので割愛します。

やりたかったけどできなかったこと

スライド中の表の操作は以下あたりを見ていけばなんとなくある程度装飾など含めてできるんですが、セル同士の結合がどうしてもできなかったです。スプレッドシートであればMerge関数でできるみたいなんですが、スライドの開発は遅れてるのか知らないですが用意されてないみたいです。このページに新しい機能は追加され次第記載されるようなので要チェックです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away