Google Apps ScriptでWebアプリケーション作成 その6

GASのWebアプリケーションでクライアント側のJavaScriptからサーバー側の関数を呼び出すことができます。非同期通信でブラウザを書き換えることができます。

サーバー側のGASの関数でスプレッドシートから値を取得します。以下のようなスプレッドシートを作成しました。

実行URL

シート名を選択して、「取得する」ボタンをクリックすると、スプレッドシートの値を取得して表示します。

https://script.google.com/a/sugizo.info/macros/s/AKfycbzclvrd9XO3sQJAz-4MDKFetoJbz5vRJZtYyHyxxl4/dev

コメントを含めて、index.htmlが80行、コード.gsが120行です。

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <base target="_top">
    <title>Jumbotron Template for Bootstrap</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
     <!-- Bootstrap Datepicker -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">
  </head>
  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Project name</a>
          <p class="navbar-brand">ログインユーザー:<?= loginUser ?></p>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
        </div><!--/.navbar-collapse -->
      </div>
    </nav>
  
    <!-- Main jumbotron for a primary marketing message or call to action -->
    <div class="jumbotron">
      <div class="container">
        <h1>Hello, world!</h1>
        <!--Printing scriptlets 出力スクリプトレットタグ-->
        <h2><?=new Date()?></h2>

        <form name="form1" id="form1" class="form-inline">
          
          <div class="form-group">
            <label for="search_key_p">シート名: </label>
            <select name="search_key_p" id="search_key_p" class="form-control">
              <?!=getHtmlOptions()?> 
            </select>  
          </div>
          <button type="button" class="btn btn-success" onclick="search();"><span class="glyphicon glyphicon-repeat"> 取得する</span></button>←スプレッドシートから値を取得
        </form>
      </div>
    </div>
    
    <div class="container">
        <div class="col-md-12">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
        <div class="col-md-12" id="div1">
        </div>
      <hr>
      <footer>
        <p>&copy; 2020 Company, Inc.</p>
      </footer>
    </div> <!-- /container -->
 
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
    <!-- Bootstrap Datepicker -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/locales/bootstrap-datepicker.ja.min.js"></script>
   
    <script>
      function search(){  
        $('#div1').html('<img  src="https://i1.wp.com/cdnjs.cloudflare.com/ajax/libs/galleriffic/2.0.1/css/loader.gif"/> 読み込み中');
        google.script.run.withSuccessHandler(CallBack).getSpd(document.getElementById("form1"));
      }      
      function CallBack(s){
      $('#div1').html(s);
      }
    </script>
  </body>
</html>

google.script.runでGAS側の関数を呼び出せます。jQueryで戻り値でhtmlを変更しています。

コード.gs

const LOG_SHEET_ID = "1f9QNeD9MXzGJElZnvo6mmXFB4vW1qy1_T-tM58iKI9A"
const SPD_SHEET_ID = "1UEAxurUgkR9nC_-mue4WYoXNUANG0hT3qPM-OT_q4Ew"

function doGet(e)
{
  console.log(e);
  
  // getEmail()、getUserLoginId()はスクリプト実行者とスクリプトオーナーのドメインが同じ場合のみ動作する
  // 別ドメインのときはセキュリティ上、取得できない
  const userEmail = Session.getActiveUser().getEmail();
  
  // IDを指定してスプレッドシートを取得
  const logSheet = SpreadsheetApp.openById(LOG_SHEET_ID); 
  
  // シート名「log」に書き込む
  logSheet.getSheetByName('log').appendRow([new Date(), userEmail, 'doGet(e)', e]); 
  
  //index.htmlファイルからHtmlTemplateオブジェクトを生成
  const template = HtmlService.createTemplateFromFile('index');
  
  template.loginUser = userEmail;
  
  // evaluateメソッドでHtmlOutputオブジェクトを生成
  return template.evaluate().setTitle('Gas3');
}

/**
 * select の optionのhtmlタグを取得
 */
function getHtmlOptions(){
  // スプレッドシートからもってくる処理 省略
  let options = {
    'シート1': 'シート1',
    'シート2': 'シート2',
    'シート3': 'シート3'
  };
  console.log(Object.keys(options));

  //foreachで流す
  let htmlOptions;
  for (var key in options) {
    htmlOptions += `<option value="${key}">${options[key]}</option>`
  }
  console.warn(htmlOptions);
  return htmlOptions;
}

/**
 * 指定した年月とユーザーからカレンダーを取得
 */
function getSpd(e){
  
  console.log(e);
  
  // getEmail()、getUserLoginId()はスクリプト実行者とスクリプトオーナーのドメインが同じ場合のみ動作する
  // 別ドメインのときはセキュリティ上、取得できない
  const userEmail = Session.getActiveUser().getEmail();
  
  // IDを指定してスプレッドシートを取得
  const logSheet = SpreadsheetApp.openById(LOG_SHEET_ID); 
  
  // シート名「log」に書き込む
  logSheet.getSheetByName('log').appendRow([new Date(), userEmail, 'getSpd(e)', e]); 
  
  const spdSheet = SpreadsheetApp.openById(SPD_SHEET_ID); 
  
  // 表示用のテーブルを作成する
  let html = '';
  
  let sheet = spdSheet.getSheetByName(e.search_key_p);
  
  // 指定したyyyymmのシートが存在しないとき
  if(!sheet){
    return '対象のシートありません!';
  }

  //master 取得
  let rowStartIndex = 3;
  let colStartIndex = 2;
  let data = sheet.getRange(rowStartIndex, colStartIndex, sheet.getLastRow()-rowStartIndex+1, sheet.getLastColumn()).getValues();
 
  html += `
    <table class="table table-hover table-bordered">
      <thead>
        <tr>
          <th>#</th>
          <th>First Name</th>
          <th>Last Name</th>
          <th>Username</th>
        </tr>
      </thead>
      <tbody>
  `;

  for (let key in data) {
    html += `
        <tr>
          <th scope="row">${data[key][0]}</th>
          <td>${data[key][1]}</td>
          <td>${data[key][2]}</td>
          <td>${data[key][3]}</td>
        </tr>
  `;
  }

  html += `
      </tbody>
    </table>
  `;
  
  return html;
}

htmlタグはテンプレートリテラルで組み立てました。

今後、同じ処理をフレームワークVue.jsで記述するとどうなるかを調べていきます。