【2021.10.24】 GASのWebアプリでスプレッドシートの表を動的に表示する方法!
こんにちは!かれんです!
ログインした後に、その人の情報をスプレッドシート⬇︎からとって表示させたい!
と思ったので今回は、「GASのWebアプリでスプレッドシートの表を動的に表示する方法」についてです。
(これできるようになるまで、、鬼時間かかった、、)
(少しでも進めばいいと思ってるけど、、少しずつすぎ!!怒)
うん、
気を取り直して、結論からいうと、
スプレッドシートの情報をいれた配列をindex.htmlに渡す
です!
いきまうす。
(現時点でのコード最後に全部載せます!)
1. スプレッドシートの情報を配列にいれる
コード.gsに⬇︎追加
/**
* doPostへシフトの時間が入った配列を返す
*
* @return 日にちと時間が入った配列
*/
function receiveShift(name_row){
const sheets = SpreadsheetApp.openById('①'); //スプレッドシートをとってくる
const sheet = sheets.getSheetByName("シート1"); //シートをとってくる
const dates = sheet.getRange(1,3,1,16).getValues(); //日にち
const times = sheet.getRange(name_row,3,1,16).getValues(); //時間
let date; //日にち
let start_time; //スタート時間
let end_time; //終わりの時間
let shift_dates = []; //全てを格納した配列
let shift_dates_index = 0;
for(let i = 0; i<dates[0].length; i=i+2){
date = Utilities.formatDate( dates[0][i], 'Asia/Tokyo', 'dd日');
if(times[0][i] != "" && times[0][i+1] != ""){ //時間が入ってないときエラーが起きるので、入ってる時だけ格納する、空欄なら空で格納
start_time = Utilities.formatDate( times[0][i], 'Asia/Tokyo', 'HH:mm');
end_time = Utilities.formatDate( times[0][i+1], 'Asia/Tokyo', 'HH:mm');
}else{
start_time = "";
end_time = "";
}
shift_dates[shift_dates_index] = [date,start_time,end_time];
shift_dates_index++;
}
return shift_dates;
}
①スプレッドシートのid
2. 配列をindex.htmlに送る
doPost()内を変更⬇︎
template = HtmlService.createTemplateFromFile('index');
template.name = name; //名前を送る
template.shift_dates = receiveShift(judges[1]); //シフトの時間を送る(judges[1]にはその人が何行かが入っている)
return template
.evaluate()
.setTitle("最初の画面")
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
変数nameと、配列shift_datesをindex.htmlに送っている
3. 表を埋め込む
index.htmlのbody内に⬇︎追加
<div class=index-div>
<h1><?=name?>さんが提出したシフト</h1>
<table id="shift_tbl">
<tr>
<? for(let i = 0; i < shift_dates.length; i++){ ?>
<th colspan="2"><?= shift_dates[i][0] ?></th>
<? } ?>
</tr>
<tr>
<? for(let i = 0; i < shift_dates.length; i++){ ?>
<th><?= shift_dates[i][1] ?></th><th><?= shift_dates[i][2] ?></th>
<? } ?>
</tr>
</table>
</div>
4. デプロイをテストしてみる
うん、まだデザインしてないからあれやけど、、w
できた〜!!
まとめ
最後まで読んでいただき本当にありがとうございます!
今回は、「GASのWebアプリでスプレッドシートの表を動的に表示する方法」についてお伝えしました。
このようにできるようになったのは、、⬇︎のおかげです、、
(分かりやすかった、、、大感謝です、、)
じゃまたね〜♡
※現時点での実装されてる機能と全てのコード
現時点での機能こんな感じ⬇︎
・スプレッドシートの表を反映させる
現時点でのファイルこんな感じ⬇︎
・コード.gs
function doGet() {
const htmlOutput = HtmlService.createTemplateFromFile("login");
return htmlOutput
.evaluate()
.setTitle("ログイン画面")
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
function doPost(postdata){
const name = postdata.parameters.name.toString(); //ログイン時の名前
const password = postdata.parameters.password.toString(); //ログイン時のパスワード
const judges = judgeAccounts(name, password); //あっていたらtrue、間違っていたらfalseが返ってくる
let template;//次に遷移する画面
if(judges[0]==1) { //judge[0]がtrue(1)ならindex.htmlに送る
template = HtmlService.createTemplateFromFile('index');
template.name = name; //名前を送る
template.shift_dates = receiveShift(judges[1]); //シフトの時間を送る(judges[1]にはその人が何行かが入っている)
return template
.evaluate()
.setTitle("最初の画面")
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
} else { //judge[0]がfalse(0)ならerror.htmlに送る
template = HtmlService.createTemplateFromFile('error');
return template
.evaluate()
.setTitle("エラー")
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
}
/**
* doPostへnameとpassがあっているかを返す
*
* @return true or falseを返す
*/
function judgeAccounts(name, password){
const sheets = SpreadsheetApp.openById('①'); //スプレッドシートをとってくる
const sheet = sheets.getSheetByName("②"); //シートをとってくる
const accounts_name = sheet.getRange(③).getValues(); //名前とってくる
const accounts_pass = sheet.getRange(④).getValues(); //パスワードとってくる
let judge = 0;
let name_row = 0;
for(let i = 0; i < accounts_name.length; i++){ //名前とパスワードがあっていればtrue、あってなければfalseを返す
if(accounts_name[i] == name && accounts_pass[i] == password){
judge = 1;
name_row = i+2;
break;
}
}
const judges =[judge,name_row];
return judges;
}
/**
* doPostへシフトの時間が入った配列を返す
*
* @return 日にちと時間が入った配列
*/
function receiveShift(name_row){
const sheets = SpreadsheetApp.openById('①'); //スプレッドシートをとってくる
const sheet = sheets.getSheetByName("②"); //シートをとってくる
const dates = sheet.getRange(1,3,1,16).getValues(); //日にち
const times = sheet.getRange(name_row,3,1,16).getValues(); //時間
let date; //日にち
let start_time; //スタート時間
let end_time; //終わりの時間
let shift_dates = []; //全てを格納した配列
let shift_dates_index = 0;
for(let i = 0; i<dates[0].length; i=i+2){
date = Utilities.formatDate( dates[0][i], 'Asia/Tokyo', 'dd日');
if(times[0][i] != "" && times[0][i+1] != ""){ //時間が入ってないときエラーが起きるので、入ってる時だけ格納する、空欄なら空で格納
start_time = Utilities.formatDate( times[0][i], 'Asia/Tokyo', 'HH:mm');
end_time = Utilities.formatDate( times[0][i+1], 'Asia/Tokyo', 'HH:mm');
}else{
start_time = "";
end_time = "";
}
shift_dates[shift_dates_index] = [date,start_time,end_time];
shift_dates_index++;
}
return shift_dates;
}
①スプレッドシートのid
②シート名
③名前が入ってる列の範囲
④パスワードが入ってる列の範囲
・login.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="form-wrapper">
<h1>ログイン</h1>
<form method="post" action="①">
<div class="form-item">
<label for="name"></label>
<input type="name" name="name" required="required" placeholder="名前"></input>
</div>
<div class="form-item">
<label for="password"></label>
<input type="password" name="password" required="required" placeholder="パスワード"></input>
</div>
<div class="button-panel">
<input type="submit" class="button" title="Login" value="Login"></input>
</div>
</form>
</div>
</body>
</html>
①デプロイしたURL
・error.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>アクセス権限のないユーザーです</h2>
</body>
</html>
・index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class=index-div>
<h1>Hello World</h1>
<h2><?=name?>さん、こんにちは!</h2>
</div>
<div class=index-div>
<h1><?=name?>さんが提出したシフト</h1>
<table id="shift_tbl">
<tr>
<? for(let i = 0; i < shift_dates.length; i++){ ?>
<th colspan="2"><?= shift_dates[i][0] ?></th>
<? } ?>
</tr>
<tr>
<? for(let i = 0; i < shift_dates.length; i++){ ?>
<th><?= shift_dates[i][1] ?></th><th><?= shift_dates[i][2] ?></th>
<? } ?>
</tr>
</table>
</div>
</body>
</html>
・css.html
<style type="text/css">
/* Fonts */
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400); //英数字のフォント
//日本語のフォントはsans-serifで統一(もともと用意されてる)
/* Simple Reset */
* { margin: 0; padding: 0; box-sizing: border-box; }
/* body */
body {
background: #e9e9e9;
color: #5e5e5e;
font: 400 87.5%/1.5em sans-serif;
}
/* エラー画面レイアウト */
h2 {
text-align: center;
padding: 1em 0;
}
/* Form Layout */
.form-wrapper {
background: #fafafa;
margin: 3em auto;
padding: 3em 1em;
max-width: 370px;
}
h1 {
text-align: center;
padding: 1em 0;
}
form {
padding: 0 1.5em;
}
.form-item {
margin-bottom: 0.75em;
width: 100%;
}
.form-item input {
background: #fafafa;
border: none;
border-bottom: 2px solid #e9e9e9;
color: #666;
font-family: sans-serif;
font-size: 1em;
height: 50px;
transition: border-color 0.3s;
width: 100%;
}
.form-item input:focus {
border-bottom: 2px solid #c0c0c0;
outline: none;
}
.button-panel {
margin: 2em 0 0;
width: 100%;
}
.button-panel .button {
background: #f16272;
border: none;
color: #fff;
cursor: pointer;
height: 50px;
font-family: 'Open sans', sans-serif;
font-size: 1.2em;
letter-spacing: 0.05em;
text-align: center;
text-transform: uppercase;
transition: background 0.3s ease-in-out;
width: 100%;
}
.button:hover {
background: #ee3e52;
}
/* index画面レイアウト */
.index-div {
background: #fafafa;
margin: 3em auto;
padding: 3em 1em;
max-width: 370px;
}
</style>