はじめに
Github Pagesで作成中のNEXTアプリのデータベース替わりにするため、GASを作成したのですがいかんせん速度が遅いため、一回の待ち時間で全シートの全データを取得出来るようにしてみました。
全体のコードと動作
function doGet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheets();
let header;
let sheet_value;
let sheet_name;
let response_data = {};
for(i in sheet){
sheet_value = sheet[i].getDataRange().getValues();
header = sheet_value.shift();
sheet_name = sheet[i].getSheetName();
// ヘッダー名とデータを関連付け
response_data[sheet_name] = sheet_value.map((value,index,array) => {
return Object.assign(...header.map((title,i) => {
return {[title]: value[i]};
}));
});
};
const response = ContentService.createTextOutput();
response.setMimeType(ContentService.MimeType.JSON);
response.setContent(JSON.stringify(response_data));
return response;
}
個人的にオブジェクト形式からプロパティ名を指定して取得した方が使いやすいため、
以下のように各シートごとにデータをまとめ、また1行目をヘッダーとしてその列のデータと関連付けています。
↓出力結果JSON
{
{
"table_01": [
{
"ID": 1,
"data1-1": "テストデータ1",
"data1-2": "テストデータ2"
},
{
"ID": 2,
"data1-1": "テストデータ2",
"data1-2": "テストデータ3"
},
{
"ID": 3,
"data1-1": "テストデータ3",
"data1-2": "テストデータ4"
}
],
"table_02": [
{
"ID": 1,
"data2-1": "テストデータ2-1",
"data2-2": "テストデータ2-4"
},
{
"ID": 2,
"data2-1": "テストデータ2-2",
"data2-2": "テストデータ2-5"
},
{
"ID": 3,
"data2-1": "テストデータ2-3",
"data2-2": "テストデータ2-6"
}
]
}
解説
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheets();
getActiveSpreadsheet() でアクティブなすべてのスプレッドシートを取得し、
getSheets() でワークブック内のすべてのSheetオブジェクトを1次元配列で取得しています
for(i in sheet){
sheet_value = sheet[i].getDataRange().getValues();
header = sheet_value.shift();
sheet_name = sheet[i].getSheetName();
// ヘッダー名とデータを関連付け
response_data[sheet_name] = sheet_value.map((value,index,array) => {
return Object.assign(...header.map((title,i) => {
return {[title]: value[i]};
}));
});
};
ここから各シートごとに処理を行います、大まかな流れとしては
1. shift()でヘッダー部とデータ部を分割
2. 2重目のmap()で行ごとに各データをオブジェクトの形式に成形
→ 「{ ヘッダー名 : データ}」
3. 行ごとに成形したデータをスプレッド構文(...header~)で展開
→ 「{ ヘッダー名 : データ},{ ヘッダー名 : データ},{ ヘッダー名 : データ}」
4. 展開したデータをObject.assign()で結合し一つのオブジェクト内に格納
→ 「{ ヘッダー名 : データ,ヘッダー名 : データ,ヘッダー名 : データ}」
5. そのシートの全データの処理が完了したら、シート名をプロパティ名に指定して格納
→ 「 シート名 : [{ 2行目のデータ },{ 3行目のデータ } ]」
6. 以下全シートの処理が終わるまで繰り返し
const response = ContentService.createTextOutput();
テキストコンテンツをレスポンスとして返すために、 ContentServiceを使用し、Textoutputオブジェクトを作成します
response.setMimeType(ContentService.MimeType.JSON);
response.setContent(JSON.stringify(response_data));
return response;
今回はJSONを返却するためMIMEタイプをJSONに設定し、JSONのデータを返却します。
まとめ
今回はとりあえず、使いやすい形にして全データの取得をやってみました。
GASのキャッシュ機能などを活用すれば2回以降の取得の高速化が見込めるらしいので、次回挑戦してみようと思います。