GAS、はじめました。GAS(Google Apps Script)はスプレッドシート(略してスプシ)などの処理を自動化するイメージだったが、Webアプリも作れるようでやってみました!まずはスプシのデータをWebページに読み込んで、CSS、JSも設定してみました。それではいきましょう!
【目次】
- スプシをSPブラウザでも開けまぁす!
- GASでWebページ化できそう!
- GASでWebページ作ってみた!
- ファイル構成
- 「コード.gs」のコード
- HTMLテンプレート
- 「コード.gs」の設定値を読み込む
- スプレッドシートのデータを読み込む
- 外部ファイル(CSS、JS)を読み込む
- CSS設定
- JS設定
- ページの表示が不安定。。
- 最後に
※参考:Web開発環境についてのまとめ
qiita.com
スプシをSPブラウザでも開けまぁす!
スプシはPCではブラウザ、SPではアプリという使い方が基本。しかし、SPブラウザでも見る方法があった!
スプシをアプリで左上の設定アイコンを開く
詳細を開く
下の方にスクロールすると…
ブラウザのURLがある!
開くとURLをコピーできる(アクセス設定の変更も)。
ブラウザで開くとこんな感じ!
ブラウザ版を触ってみて分かったこと。
- ブラウザ版は閲覧のみで編集はできない模様(右上の鉛筆アイコンを押すとアプリが開いた)
- ブラウザでは行や列の固定設定が効かず、表が大きくなったときに見づらい。。
- 画面の拡大縮小も拡大はできるが縮小がある程度より先はできないっぽい
GASでWebページ化できそう!
SPブラウザで見る時に、固定設定を効かせたい。CSSを自分で設定できればいいんだけどなー。
「スプレッドシート CSS設定」などで調べていると、下記の記事に出会った。
※参考:Google Apps ScriptのWebアプリケーションにCSSでスタイル設定をする
お?GASでCSSを設定?それなら自由自在やん♪
さらにシリーズ記事の源流を辿ると「GASを使ってスプシからWebアプリを作る」という内容だった!
※参考:Google Apps ScriptでWebアプリケーションを作る最初の一歩
※参考:Google Apps Scriptで作るWebページにスクリプトの結果を出力して表示してみる
※参考:Google Apps ScriptでWebアプリケーションにスプレッドシートの値を出力する
※参考:Google Apps ScriptのWebアプリケーションにCSSでスタイル設定をする
はじめの一歩としてWebページを作っているがさらに理解を深めればWebアプリも作れそう。スプシがDBになるということだ。
オラ、ワクワクしてきたぞ。いっちょやってみっかー!
GASでWebページ作ってみた!
早速作ってみた。
元のスプシデータがこちら
Webを開くと最初にJSが動いてアラートが出る
アラートを閉じるとCSSが効いたWebページが表示される
スプシ以外のテキストも設定している。
ファイル構成
GASはJSとほぼほぼ同じ記法だったのでかなり分かり易かった。GASで予め用意されているメソッドを利用するJS、というイメージ。
「ツール>スクリプトエディタ」のサイドバーがファイル構成。
- コード.gs:関数設定のファイル
- appsscript.json:アプリの設定値のjsonファイル
- index.html:表示されるページのHTMLファイル
- css.html:CSS設定ファイル
- js.html:JS設定ファイル
「コード.gs」が初期からあるファイル。拡張子もgsでGASのメソッドを直接書ける。
「appsscript.json」はnpmのpackage.jsonみたいな内容。初期は表示されない。
「index.html」が表示しているページ部分だが、外部のデータを読み込むテンプレートタグを埋め込んでいる。
「css.html」「js.html」はhtmlファイルだが中にはCSS、JS設定を書いている。index.htmlで読み込んでいる。
「コード.gs」のコード
初期ではこのコードが書かれている。
function myFunction() { Browser.msgBox("Hello World"",Browser.Buttons.OK) }
これは使わないのでまるまる削除する。
下記の3つの関数を設定している。
function doGet() { return HtmlService.createTemplateFromFile('index').evaluate(); } function getData(alg) { if (alg == 'title') { return 'ザ・ビートルズ'; } else if (alg == 'summary') { return 'ビートルズのメンバーを紹介します'; } } function include(filename) { return HtmlService.createHtmlOutputFromFile(filename).getContent(); }
doGet()
関数:HTMLページを表示するgetData()
関数:ページで読み込む文字列データを設定include()
関数:ページで読み込む外部ファイルを設定
詳細は後述。
HTMLテンプレート
「index.html」のコード
<!DOCTYPE html> <html> <head> <base target="_top"> <title><?= getData("title"); ?></title> <meta name="description" content="<?= getData("summary"); ?>"/> <?!= include('css'); ?> <?!= include('js'); ?> </head> <body> <h1><?= getData("title"); ?></h1> <p><?= getData("summary"); ?></p> <table> <? const myData = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); for(var i=0;i<myData.length;i++){ // output.append('<li>' + myData[i][0] + '</li>'); output._ = '<tr><td>' + myData[i][0] + '</td><td>' + myData[i][1] + '</td></tr>'; } ?> </table> </body> </html>
基本的にはHTMLタグだが、一部に <? ?>
のテンプレートタグが埋め込まれている。詳細は後述。
このページを表示させる設定は「コード.gs」のdoGet()
関数
function doGet() { return HtmlService.createTemplateFromFile('index').evaluate(); }
- 関数
doGet()
を定義 HtmlService
オブジェクト のcreateTemplateFromFile()
メソッドを実行(引数はindex
)- 続いて
evaluate()
メソッドを実行 - 結果を
return
で返す
createTemplateFromFile()
でファイルを読みこむ。index
でindex.html。evaluate()
でHTMLオブジェクトにする。
※参考:Google Apps ScriptでWebアプリケーションを作る最初の一歩
「コード.gs」の設定値を読み込む
「index.html」のhead
タグ
<title><?= getData("title"); ?></title> <meta name="description" content="<?= getData("summary"); ?>"/>
「index.html」のbodyタグ
<h1><?= getData("title"); ?></h1> <p><?= getData("summary"); ?></p>
これらに埋め込んでいるテンプレートタグの中でgetData()
関数を実行している。引数でデータを指定している。
<?=
と=
がつくのは「出力スクリプトレットタグ」と言って関数の結果を表示する機能。
getData()
関数は「コード.gs」に設定している
function getData(alg) { if (alg == 'title') { return 'ザ・ビートルズ'; } else if (alg == 'summary') { return 'ビートルズのメンバーを紹介します'; } }
- 関数
getData()
を定義(引数はalg
) - もし
alg
がtitle
だったら「ザ・ビートルズ」という文字列を返す - またはもし
alg
がsummary
だったら「ビートルズのメンバーを紹介します」という文字列を返す
これが先ほどの「index.html」に読み込まれる。
※参考:Google Apps Scriptで作るWebページにスクリプトの結果を出力して表示してみる
スプレッドシートのデータを読み込む
次はスプレッドシートのデータを読み込む。
「index.html」のtabelタグ
<table> <? const myData = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); for(var i=0;i<myData.length;i++){ // output.append('<li>' + myData[i][0] + '</li>'); output._ = '<tr><td>' + myData[i][0] + '</td><td>' + myData[i][1] + '</td></tr>'; } ?> </table>
- 変数
myData
でSpreadsheetApp
オブジェクトのgetActiveSheet()
メソッド、getDataRange()
メソッド、getValues()
メソッドを実行 - for文で
myData
の数分繰り返し output
の_
プロパティをtl
、td`タグ(2つ)に- 一つ目の
td
でmyData
の多次元配列i
番目の0
番目、2つ目のtd
でi
番目の1
番目を入れる
こちらの<?
は=
を付けていない。これは「スタンダードスクリプトレットタグ」と言って関数の結果を読み込むのではなくこの中に直接スクリプトを書く時に使う。
※参考:Google Apps ScriptでWebアプリケーションにスプレッドシートの値を出力する
myData
の中のメソッドはGASの組み込みメソッドで、結果は多次元配列になるようだ。
参考記事では1列のデータを読み込んでli
タグに入れている
'<li>' + myData[i][0] + '</li>'
この多次元配列[i][0]
のi
が行数、0
が列数と見受けられたので0
を1
にしたら2列目のデータを読み込めた!そこでtable
のtd
タグにして2列分読み込んだ!
'<tr><td>' + myData[i][0] + '</td><td>' + myData[i][1] + '</td></tr>'
なお、getRange()
メソッドを使うとさらに細かいセルの範囲指定ができるっぽい。
※参考:getRangeいろいろ(Google Apps Script、SpreadSheet) - Qiita
参考記事で使われている.append()
メソッドはV8エンジンになって少し書き方が変わったようだ。
output.append(sth)
を
output._ = sth
の形に修正してみたら、V8でも私のところでは動いてくれました。
※参考:JavaScript - GAS エラーの原因がわからない|teratail
※参考:Google Apps Script の暗黙オブジェクト - Qiita
V8ランタイムとは?
※参考:V8 (JavaScriptエンジン) - Wikipedia
つーか、JavaScriptエンジンとは?
※参考:JavaScriptエンジン - Wikipedia
なお、この処理を行う時に、下記の記事と同じエラーがあった。
「表示→マニフェスト ファイル」で「appsscript.json」を表示して、下記の設定を追記する。
"oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/spreadsheets"]
「appsscript.json」のコード
{ "timeZone": "Asia/Tokyo", "dependencies": { }, "webapp": { "access": "ANYONE_ANONYMOUS", "executeAs": "USER_DEPLOYING" }, "exceptionLogging": "STACKDRIVER", "oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/spreadsheets"], // ここに追記 "runtimeVersion": "V8" }
以下、参考記事の手順で設定を適用した。
記事にもあるように「詳細→〇〇(安全ではないページ)に移動で許可」がとてもわかりにくいUIだった(「安全なページに戻る」の方が目立ってつい押したくなるw)
※参考:GASのエラー”呼び出す権限がありません”はマニフェストファイルに問題あり - Qiita
外部ファイル(CSS、JS)を読み込む
HTMLにCSS 、JS設定も行いたい。
「index.html」のhead
タグの中で読み込む。
<?!= include('css'); ?> <?!= include('js'); ?>
include()
関数で外部ファイルを読み込み(引数がファイル名)
<?!=
は「強制出力スクリプトレットタグ」と言って、外部ファイルのコードがエスケープ(コード丸ごと表示)されるのを防ぐ。
include()
関数は「スクリプト.ga」に設定している
function include(filename) { return HtmlService.createHtmlOutputFromFile(filename).getContent(); }
include()
を定義(引数はfilename
)HtmlService
オブジェクト のcreateHtmlOutputFromFile()
メソッドを実行(引数はfilename
)- 続いて
getContent()
メソッドを実行
いずれもGASの組み込みメソッド
※参考:Google Apps ScriptのWebアプリケーションにCSSでスタイル設定をする
CSS設定
CSS設定はcssファイルではなくhtmlファイルにstyle
タグで囲って書く。
「css.html」
<style> body { font-family: sans-serif; } h1 { font-weight: bold; font-size: 1.5em; } tr:first-child { background: #666; color: #fff; text-align: center; } td { border-bottom: 1px solid #ccc; padding: 5px; } </style>
body
全体をゴシック体にh1
タグを太字で1.5倍サイズにtr
タグの1行目は背景を濃いグレー、文字を白、センター寄せtg
タグは下線を入れて、余白を5px
これで先ほどのスタイルが当たった!
JS設定
JS設定もjsファイルではなくhtmlファイルにscript
タグで囲って書く。
「js.html」
<script> alert('ビートルズがやって来る ヤァ!ヤァ!ヤァ!'); </script>
- ページ読み込み時にアラートで「ビートルズがやって来る ヤァ!ヤァ!ヤァ!」を表示する
CSSもJSもhtmlで作成したが、これってつまりHTMLタグもテンプレート的にモジュール化して埋め込めるってことだよね!ヘッダー、フッターとか。CSS やJSも複雑な構成はモジュール分割できるかも!
ページの表示が不安定。。
作ったページの公開はこちらの手順に従って「全ユーザー」とかにしてみたんだが…
※参考:Google Apps ScriptでWebアプリケーションを作る最初の一歩
PCやSPのいろいろなブラウザでURLを開いてみると、どうもうまく表示されない時がある。。
PCではこのような真っ白な画面になったり…
調べると、白い画面ではSafariでは「Sandbox」のエラーメッセージがあった。
※参考:Safari:sandboxのエラー - Qiita
Sandboxとは
※参考:https://wa3.i-3-i.info/word16589.html
SPでは「現在アプリを開くことができません」となったり…
「現在アプリを開くことができません」はブラウザで複数のGoogleアカウントを使っているのが原因だよ、とか。
※参考:現在、ファイルを開くことができません。(GAPGoogle Apps Script) | ハンノマライフ。
でもいまいちアカウント設定を変えても解決したりしなかったりする。
あと、変更がなかなか反映されなかったりもする。
なかなか反映されないのはバージョンの番号をあげるといいらしい。
※参考:Google Apps Script (GAS) で更新が反映されない場合の対処 | ハックノート
また、アプリのURL欄の下の方にある「latest code」という小さいリンク。こちらから開く場合は問題なく最新版が表示される。
これは「開発モード」でurlの最後がdev
になっている(本番公開用のURLはexec
)
※参考:GAS webアプリ公開時のexecとdev - Qiita
修正中はこちらで確認する方が良さそう。
ちなみにページ上部に表示されて目立つ「このアプリケーションは、Google ではなく、別のユーザーによって作成されたものです。」
これは2017年以降に表示されるようになったらしい。こちらに対処法などがあった。
※参考:Pre-Practice Blog: HTML Serviceで作ったWebアプリの上部に表示されるバナーについて
最後に
ということでスプレッドシートのデータをGASで読み込んでWebページを作りました!CSSやJSを自由に設定できるのはいいですね♪モジュール分割もできるのでスプシをDB代わりにしたCMS見たいのも作れそう。
このページ上にフォームを作って、そこからスプシのデータにCRUD操作してみたい。そうするとWebアプリっぽくなっていくと思う。
それではまた!
※参考:Web開発環境についてのまとめ
qiita.com