見出し画像

【イチからDX】GASでGoogleスライドのテキスト置換・画像変換に挑戦してみた

弊社の研修プログラムを修了した受講者の方には修了証をお送りしています。まだ改善の余地はあるものの、修了証の作成業務を9割程度自動化することに成功したので、その方法をご紹介したいと思います🐰💡


*今回の目的

Googleスライドを使って修了証を作成するのですが、氏名・受講したプログラム・修了日といった情報を書き換えて、ファイル名をつけて…という繰り返し作業が担当者の負担になっていました。また個人情報を扱う作業であるため、ミスを予防するという観点からも自動化に挑戦しました。


*今回のゴール

今回は修了者の情報を所定のスプレッドシートにコピペしたのちにGASを実行することで、修了証作成から画像を保存する工程までを自動化します。


*用意するもの

あらかじめ以下のものを用意しておきます。
①修了者情報を入力するためのスプレッドシート
②修了証のテンプレート(複製元)となるスライド
③GASで作成したファイルを格納する親フォルダ

ファイル・フォルダの格納場所は共有ドライブ等でも大丈夫です

*修了者リスト/スプレッドシート

今回使う情報は修了者の氏名、会社名、プログラム、修了日です。

GASで作成したフォルダへのリンクをG4セルに自動入力させます

*修了証テンプレート/スライド

以下の情報を修了者ごとに書き換えます。
⚠️なお、編集したいもの以外のテキストボックスや画像は「表示」タブ→「テーマ作成ツール」にて作成しておいてください(詳しくは補足編を参照ください)。

{name} →受講者の氏名
{program} →修了したプログラム名
{yyyy/mm/dd} →修了日


*全体の流れ

GASで自動化するのは②〜⑤までの工程です。
今回ご紹介するコードでは(私の力不足で😥)スライドファイルを人数分複製・保存するようになっています。ファイルの数が嵩張りますので、気になる場合は工夫をしてみてください。


*設定方法

修了者リストを作成したスプレッドシートで「拡張機能」→「Apps Script」をクリックしてコード編集画面を開きましょう。

*コード全文

以下のコードをコピペし、必要箇所だけご自分の状況に合わせて修正ください。いくつか補足説明をしますので、必要な方は最後までご覧頂けますと幸いです🐰🌸

function note_mochi() {
  //開いているスプレッドシートファイルを取得
  var spreadsheet = SpreadsheetApp.getActive();
  
  //修了者リストのシートを取得
  var sheet = spreadsheet.getSheetByName('***シート名***'); //シート名を差し替え
  
  //保存先のフォルダを指定
  var folder1 = DriveApp.getFolderById('***フォルダID****'); //フォルダIDを差し替え


  //修了証の作成に必要な情報を取得していきます。(受講者共通の情報。氏名は後で取得します)
  //(1)受講者の会社名を取得
  var company = sheet.getRange('G1').getValue(); //セル番号を差し替え
  Logger.log(company);

  //(2)修了プログラム名を取得
  var program = sheet.getRange('G2').getValue(); //セル番号を差し替え
  Logger.log(program);

  //(3)修了日を取得(※ここではスプレッドシートに記載の日付を使用)
  var fhinishday = sheet.getRange('G3').getValue(); //セル番号を差し替え
  var fhinishdate = Utilities.formatDate(fhinishday,'JST','yyyy年MM月dd日'); //日付の表記方法を指定
  Logger.log(fhinishdate);


  //修了証を格納するための新規フォルダを作成します(※ここでは会社名で作成)
  var folder2 = folder1.createFolder(company); //フォルダ名を差し替え
  Logger.log(folder2);

  //新規フォルダのIDをスプレッドに書き出し(※省略可)
  var folder2_ID = folder2.getId();
  sheet.getRange('G4').setValue('https://drive.google.com/drive/folders/' + folder2_ID); //セル番号を差し替え


  //ここから修了証の作成に入ります。
  //定義したもの以外のテキストボックスや図形が編集可能な状態にあるとエラーが出るため、
  //テーマ作成ツールでテンプレートとして保存しておいてください。

  //テキスト置換のための下準備です。(★)
  //置換を行いたいテキストボックスの数だけ以下のように定義します。
  //「''」内をテキストボックスのオリジナルテキスト(置換前のテキスト)に差し替えてください。
  var id_name = '{name}';
  var id_program = '{program}';
  var id_report_date = '{yyyy/mm/dd}';

  //修了者リストを全行取得します。
  var sheetRows = sheet.getDataRange().getValues();

  //修了証のテンプレートを複製し、人数分作成していきます。
  //※リストの受講人数分、繰り返し実行します。あまり人数が多いとタイムアウトになるので分けて行ってください。

  sheetRows.forEach(function (row, i) {
  // 1行目はヘッダーなので除外する
  if (i === 0) {
   return;
  }
  //氏名が入った列を指定(B列=1)
  var name = `${row[1]}`; //列を差し替え

  //ファイル名を指定(複製したスライドおよび画像出力した際のファイル名として使います。違う名前にすることも可能です)
  var proof_name = '修了証_'+ name +'殿'; //ファイル名を差し替え

  //修了証テンプレートのスライドファイルを複製
  var templatefile1 = DriveApp.getFileById('***スライドファイルID***'); //ファイルIDを差し替え
  var copied_proof = templatefile1.makeCopy(proof_name, folder2); //ファイル名、保存フォルダを指定

  //複製したファイルを取得し、テキスト置換を行います。
  //コピーしたファイルのID取得
  var cp_id = copied_proof.getId();

  //コピーしたファイルを編集する準備
  var slides_file = SlidesApp.openById(cp_id);
  var slides =slides_file.getSlides();

  //今回は1ページ目(=0)のみ編集します。
  var page_no = 0
  var slide = slides[page_no];
  var pageElements = slide.getPageElements();

  //スライドのテキストボックス(シェイプ)を取得
  for(var shape_no=0;shape_no<pageElements.length;shape_no++){
    //指定のフォーマットの文字列を置換(★で指定したID,置換後テキスト)
    pageElements[shape_no].asShape().getText().replaceAllText(id_name, name);  //テキスト置換1
    pageElements[shape_no].asShape().getText().replaceAllText(id_program, program);  //テキスト置換2
    pageElements[shape_no].asShape().getText().replaceAllText(id_report_date,fhinishdate );  //テキスト置換3
  }

  //編集したスライドを保存(これがないと最初に取得したスライドの状態のまま画像変換されるので注意)
  slides_file.saveAndClose();

  //修了証をスライドから画像に変換します
  //変換url(エクスポート)
  var export_url = 'https://docs.google.com/presentation/d/'+ cp_id +'/export/png';  //ファイル形式を指定
  //オプションを指定
  var options = {
    method: "get",
    headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true
  }
  var res = UrlFetchApp.fetch(export_url, options);
  if (res.getResponseCode() === 200) {
  folder2.createFile(res.getBlob()).setName(proof_name + ".png");  //ファイル名、保存フォルダを指定
 }

 });

}

*補足説明

シート名は「'(アポストロフィ)」で囲んでください。

  //修了者リストのシートを取得
  var sheet = spreadsheet.getSheetByName('***シート名***'); //シート名を差し替え

フォルダやファイルのIDは画像のようにURLから取得できます。

  //保存先のフォルダを指定
  var folder1 = DriveApp.getFolderById('***フォルダID****'); //フォルダIDを差し替え

今回、日付情報はGASの中で取得していません。もし日付情報を当日などに自動設定したい場合には、スプレッドシートの方で関数「=today()」を使うと良いでしょう。

  //(3)修了日を取得(※ここではスプレッドシートに記載の日付を使用)
  var fhinishday = sheet.getRange('G3').getValue(); //セル番号を差し替え
  var fhinishdate = Utilities.formatDate(fhinishday,'JST','yyyy年MM月dd日'); //日付の表記方法を指定
  Logger.log(fhinishdate);

弊社の研修は基本的に会社ごとのグループで受講いただくため、情報を都度取得し直す必要があるのは氏名だけでした。ですので氏名についてはsheetRows.forEach(function (row, i) の中でファイル作成を繰返す度に一行ずつ下のセルを参照させるようにしています。

  //氏名が入った列を指定(B列=1)
  var name = `${row[1]}`; //列を差し替え

色々なサイトやブログを参考にさせていただきながらコードを作成しましたが、編集したいページが複数あると難易度が高くなるようです。
今回は無理をせず1ページだけのテンプレートを用意し、これを編集(テキスト変換)するようにしています。

  //今回は1ページ目(=0)のみ編集します。
  var page_no = 0
  var slide = slides[page_no];
  var pageElements = slide.getPageElements();

実は今回最も苦労した点がこちら。画像変換がうまくいってもテンプレートのまま(テキスト置換前)という問題を中々解決できませんでした💦
Googleスライドやドキュメントは自動保存されるもの、という認識でしたが、今回のようなケースでは「saveAndClose()」が必要みたいです。

  //編集したスライドを保存(これがないと最初に取得したスライドの状態のまま画像変換されるので注意)
  slides_file.saveAndClose();

画像変換に関してはこちらの記事を参考にさせていただきました。

  //修了証をスライドから画像に変換します
  //変換url(エクスポート)
  var export_url = 'https://docs.google.com/presentation/d/'+ cp_id +'/export/png';  //ファイル形式を指定
  //オプションを指定
  var options = {
    method: "get",
    headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true
  }
  var res = UrlFetchApp.fetch(export_url, options);
  if (res.getResponseCode() === 200) {
  folder2.createFile(res.getBlob()).setName(proof_name + ".png");  //ファイル名、保存フォルダを指定

GASを実行して作成されたファイルと画像がこちら。何か修正があった際にはスライドのまま残しておいた方が便利ですが、不要ならば削除まで自動化しても良いかもしれませんね。


*さいごに

修了証の中に入力する氏名とファイル名として入力する氏名、いつか必ず間違えると思っていたので自動化できて安心しています🐰
今回の記事だけでは説明が足りない部分もあると思いますが、長くなってしまったので次回に保留とします。またご覧頂けたら嬉しいです。


******************************

🐰おすすめ記事🐰


いいなと思ったら応援しよう!