📝

【AWS×GAS】S3のファイルをスプレッドシートから読み込む

8 min read

概要

GASを用いてAWS S3上に保存されているファイルを、スプレッドシートから読み込む方法を解説します。
ドキュメント詳細ページだけでは、GASの新エディタやライブラリのバージョンでハマりポイントがあったのでまとめてみました。

IAMユーザー作成

AWS S3にアクセスするための権限を持ったAIMユーザーを作成します。

AWS マネージメントコンソールから、IAMと検索し、IAMのページにアクセス。

左側のメニューからユーザーをクリック。

ユーザーを追加をクリック

分かりやすい名前を入力し、プログラムによるアクセスにチェックを入れて次のステップ:アクセス権限をクリック。

既存のポリシーを直接アタッチを選択し、ポリシーのフィルタ(検索欄)にS3Readと入力して、AmazonS3ReadOnlyAccessを選択し、次のステップ:タグをクリック。

タグは何も入力せずに次のステップ:確認をクリック。
(作成するIAMユーザーに説明をつけたい場合はName等でラベリングができます。)

入力内容を確認してユーザーの作成をクリック。

アクセスキーIDシークレットアクセスキーをメモに控える(CSVのダウンロードでも可能です)
アクセスキーIDとシークレットアクセスキーは後程GASを記述する際に使います。

ここで表示されるアクセスキーIDとシークレットアクセスキーは絶対に公開しないでください。
こちらのアクセスキーIDとシークレットアクセスキーを利用することで、誰でもこのAWS環境にアクセスすることが可能です。
今回作成したIAMユーザーはS3ReadOnly権限のみなので、万が一漏洩した場合はS3の読み取りが自由に行えるようになります。

S3バケット作成

AWS マネージメントコンソールから、S3と検索し、S3のページにアクセス。

画面右上からバケットを作成をクリック。

次のように設定し、バケットを作成をクリック。

項目名 説明
バケット名 分かりやすい名前を入力(今回はsample-read-file-from-spreadsheetとしています) ここで入力する名前は一意である必要があります。
リージョン アジアパシフィック (東京) ap-northeast-1 バケットが作成される場所
ブロックパブリックアクセスのバケット設定 パブリックアクセスをすべて ブロック バケットを一般公開するかどうか。今回はIAMユーザーを作成してアクセスするため、パブリックアクセスをすべてブロックとしています
バケットのバージョニング 無効にする 名前の通りバージョン管理をするかどうか。今回はサンプルのため無効にしていますが、実際にプロダクトを運用する場合は有効にしておくと、意図せず書き換えた際に復元ができるようになります。


バケットが作成されたら、バケット名をクリック

アップロードをクリック。

ファイルを追加をクリックし、適当なファイルを選択。

今回アップロードするファイルは↓

sample.txt
sample content

アップロードをクリック。

GASを作成

ライブラリをインポート

スプレッドシートを新規作成し、ツールスクリプトエディタをクリック。

右上にある以前のエディタを使用をクリック。

新しいエディタの左側メニューにあるライブラリの+ボタンから検索するとうまく表示されません。

上部メニューからリソースライブラリをクリック。

Add a libraryに MB4837UymyETXyn8cv3fNXZc9ncYTrHL9 と入力して追加をクリック。

バージョンを3にして保存をクリック。

バージョン4だと後程利用するgetObjectメソッドが機能しません。

S3から読み取るコードを記述

ライブラリのインポートが完了したら新しいエディタに切り替えます(ここはお好みで)

S3からファイルをロードする関数

S3から指定したファイルを読み込むgetS3Fileを定義します。
アクセスキーIDおよびシークレットアクセスキーはIAMユーザー作成時に控えたものを貼り付けてください。

スプレッドシートを一般公開する場合はGASに直接アクセスキーIDとシークレットアクセスキーを書くと、IAMユーザーの情報が公開されてしまいますので、ご注意ください。

GAS
/**
 * S3からファイルをロード
 * @params {string} bucketName - 読み取りたいS3のバケット名
 * @params {string} fileName - 読み取りたいファイル名
 */
function getS3File(bucketName, fileName) {
  // S3の接続情報
  const ACCESS_KEY_ID = "アクセスキーID";
  const SECRET_ACCESS_KEY = "シークレットアクセスキー";

  const s3 = S3.getInstance(ACCESS_KEY_ID, SECRET_ACCESS_KEY); 
  // バケット名とファイル名を指定してファイルの中身を取得
  const data = s3.getObject(bucketName, fileName);
  return data;
}

スプレッドシートに反映する関数

続いて引数に渡された値をスプレッドシート反映する関数を作成します。
今回はサンプルのため、1行1列目に出力していますが、取得するデータ量やファイル形式に応じて適宜出力方法は変えてください。
(最後に各ファイルに応じたパターン例を載せていますのでご参考ください)

GAS
/**
 * S3からファイルをロード
 * @params {string} bucketName - 読み取りたいS3のバケット名
 * @params {string} fileName - 読み取りたいファイル名
 */
function getS3File(bucketName, fileName) {
  // S3の接続情報
  const ACCESS_KEY_ID = "アクセスキーID";
  const SECRET_ACCESS_KEY = "シークレットアクセスキー";

  const s3 = S3.getInstance(ACCESS_KEY_ID, SECRET_ACCESS_KEY); 
  // バケット名とファイル名を指定してファイルの中身を取得
  const data = s3.getObject(bucketName, fileName);
  return data;
}

+ /**
+  * スプレッドシートに値を出力
+  * @params {string} data - スプレッドシートに出力する値
+  */
+ function exportDataToSpreadSheet(data) {
+   const sheet = SpreadsheetApp.getActiveSheet();
+   sheet.getRange(1, 1).setValue(data);
+ }

作成した関数を呼び出すメイン部分

それでは以上2つの関数を呼び出すmain関数を作成ましょう。

GAS全文
/**
 * S3からファイルをロード
 * @params {string} bucketName - 読み取りたいS3のバケット名
 * @params {string} fileName - 読み取りたいファイル名
 */
function getS3File(bucketName, fileName) {
  // S3の接続情報
  const ACCESS_KEY_ID = "アクセスキーID";
  const SECRET_ACCESS_KEY = "シークレットアクセスキー";

  const s3 = S3.getInstance(ACCESS_KEY_ID, SECRET_ACCESS_KEY); 
  // バケット名とファイル名を指定してファイルの中身を取得
  const data = s3.getObject(bucketName, fileName);
  return data;
}

/**
 * スプレッドシートに値を出力
 * @params {string} data - スプレッドシートに出力する値
 */
function exportDataToSpreadSheet(data) {
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1).setValue(data);
}

+ function main(){
+   const bucketName = "sample-read-file-from-spreadsheet";
+   const fileName = "sample.txt";
+ 
+   const data = getS3File(bucketName, fileName);
+   exportDataToSpreadSheet(data)
+ }

実行

それでは関数を実行してみましょう。

実行する関数をmainにし、実行をクリック。

実行時に次のようなポップアップが表示された場合は許可を確認をクリック。

正常に実行できれば以下のようにスプレッドシートにS3にアップロードしたsample.txtの中身が出力されます。

以上がS3のファイルをスプレッドシートから読み取る方法でした。

TIPS

JSONファイルの読み取り

以下のようなJSONファイルをロードする場合

sample.json
{
    "1": {
        "name": "山田",
        "age": 20
    },
    "2": {
        "name": "田中",
        "age": 23
    }
}

次のようにJSON.parseでオブジェクト形式に変換できます。

GAS
(省略)
function main() {
  (省略)
  const res = getS3File(bucketName, fileName);
  const data = JSON.parse(res)
}

CSVファイルの読み取り

以下のようなCSVファイルをロードする場合

sample.csv
id, name, age
1, 山田, 20
2, 田中, 23

次のように配列に変換してスプレッドシートに反映します。

GAS
(省略)
function main() {
  (省略)
  const res = getS3File(bucketName, fileName);
  const data = res.split('\n')
  const arr = []
  for(const row of data){
    arr.push(row.split(','))
  }
}

サブディレクトリにあるファイルの読み取り

S3のディレクトリ内にあるファイルを読み取る場合はパスから記述します。
例としてS3上のsampleDirというディレクトリの中にあるsample.txtの中身を読み込む場合は次の通りです。

sampleDir
|_ sample.txt
GAS
(省略)
function main() {
  (省略)
  const fileName = "sampleDir/sample.txt";
  const res = getS3File(bucketName, fileName);
  (省略)
}

参考

https://engetc.com/projects/amazon-s3-api-binding-for-google-apps-script/