ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【GAS/Googleスプレッドシート】CSVファイルをアップロードしてGoogleスプレッドシートに内容を入力する

 ものすごく久しぶりにGoogle Apps Script(GAS)を触ってみています。

 今回はタイトルにあるようにCSVファイルをアップロードしてスプレッドシートに内容入力するというのをやってみた備忘録になります。

 では始めます。


1:新規にスプレッドシートの作成する
 Googleドライブ上で右クリックして「Googleスプレッドシート」をクリックして作成します。
f:id:rikoubou:20200317173916p:plain

 新規のスプレッドシートが開くのでファイル名を「CSVアップロード」に変更し、メニューの「ツール」→「スクリプトエディタ」をクリックしてスクリプトエディタを開きます。
f:id:rikoubou:20200317174315p:plain


2:.gsファイルと.htmlファイルの作成
 スクリプトエディタを開くと以下のような画面になります。
「このプロジェクトは Chrome V8 を搭載した新しい Apps Script ランタイムで実行しています。」というメッセージが表示されますが、今回は無視します(これについては「おまけ:V8 Runtimeについて」の項目で軽く説明します)。
f:id:rikoubou:20200317174452p:plain

「無題のプロジェクト」という部分をクリックするとプロジェクトに名前を付けられるので「CSVアップロードプロジェクト」に変更します。
f:id:rikoubou:20200317174857p:plain

 名前を変更したらコード.gsの内容を以下のように書き換えます。
 
・コード.gs

// メニューの追加
function onOpen() {
  SpreadsheetApp.getUi()
      .createMenu('追加メニュー')
      .addItem('CSVアップロード', 'csvDialog')
      .addToUi();
}

// ダイアログを表示
function csvDialog() {
  var html = HtmlService.createHtmlOutputFromFile('index');
  SpreadsheetApp.getUi().showModalDialog(html, 'CSVアップロード');
}

// アップロード処理
function uploadProcess(formObject) {
  var formBlob = formObject.myFile;
  var csvText = formBlob.getDataAsString();    
  var values = Utilities.parseCsv(csvText);
  SpreadsheetApp.getActiveSheet().getRange(1, 1, values.length, values[0].length).setValues(values);
}

 コード.gsを書き換えたら「ファイル」→「New」→「HTMLファイル」を選択してhtmlファイルを追加します。
f:id:rikoubou:20200317175327p:plain
 
 追加するhtmlファイル名を尋ねられるので「index」と入力してOKボタンを押します。
f:id:rikoubou:20200317175544p:plain

 するとindex.htmlファイルが作成されます。
f:id:rikoubou:20200317175653p:plain

 作成したindex.htmlの中身を以下のように書き換えます。

・index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      // アップロードボタンが押された時の処理
      function csvUpload(formObject) {
        google.script.run.withSuccessHandler(closeDialog).uploadProcess(formObject);
        document.getElementById('myForm').style.display = 'none'; // フォームを非表示
        document.getElementById('message').innerHTML = '処理中...'; // 処理中の文字を表示
      }
      
      // 処理が終わった時にダイアログを閉じる
      function closeDialog() {
        google.script.host.close();
      }
    </script>
  </head>
  <body>
    <form id='myForm'>
      <input name="myFile" type="file" />
      <button onclick="csvUpload(this.parentNode);">アップロード</button> 
    </form>
    <div id='message'></div>
 </body>
</html>

 これでGASとhtml部分の記述は終了ですが、次の手順でV8 Runtimeを無効にします。


3:V8 Runtimeを無効にする
 V8 Runtimeが有効の状態だとなぜかうまく動かないので、V8 Runtimeを無効にします。

「実行」→「Chrome V8を搭載した新しいApps Script ランタイムを無効にする」をクリックします。
f:id:rikoubou:20200317180314p:plain

 以下のようなメッセージが表示されていればV8 Runtimeが無効になっています。
f:id:rikoubou:20200317180447p:plain


4:動作確認
 1~3まで出来たら「CSVアップロード」のスプレッドシートを開きなおします。

 開いてしばらく待つと「追加メニュー」という項目が追加されています。そこを選択して「CSVアップロード」をクリックします。
f:id:rikoubou:20200317181005p:plain

 初めて実行すると以下のように承認を求められるので「続行」ボタンをクリックします。
f:id:rikoubou:20200317181319p:plain

 承認するアカウント選択画面になるので、承認するアカウントを選択してクリックします。
f:id:rikoubou:20200317181431p:plain

 すると以下のような画面が表示されるので左下にある「詳細」をクリックします。
f:id:rikoubou:20200317181538p:plain

 詳細の一番下にある「CSVアップロードプロジェクト(安全ではないページ)に移動」をクリックします。
f:id:rikoubou:20200317181648p:plain

 承認するアカウントと許可する項目が表示されるので、一番下にある「許可」をクリックします。
f:id:rikoubou:20200317181736p:plain

 これで承認が完了します。承認したアカウントにセキュリティのメールが届くのでアクティビティを確認しておいてください。
 また一度承認すればこの手順は不要になります。

 承認が完了した状態で「CSVアップロード」をクリックすると、以下のようなダイアログが表示されます。
f:id:rikoubou:20200317182041p:plain

 例えば今回は以下のようなCSVファイルを用意してアップロードしてみます。

・test.csv

test,test1,test2
1,2,3

「ファイル選択」ボタンを押してCSVファイルを指定し「アップロード」ボタンをクリックします。
f:id:rikoubou:20200317182428p:plain

 するとボタンが消えて「処理中...」という文字が表示されます。
f:id:rikoubou:20200317182450p:plain

 処理が完了すると自動的にダイアログが閉じ、スプレッドシート上にCSVの内容が入力されます。
f:id:rikoubou:20200317182549p:plain


 以上がCSVファイルをアップロードしてGoogleスプレッドシートに内容を入力する方法です。

 昔自分がやっていた記述だとできなかったりしたので、色々変わっているみたいでした。
 クラウド関係を使う場合は時々でも動向をチェックしておいた方がいいのかもしれないですね…。


おまけ:V8 Runtimeについて
 自分が触っていない間にGASのデフォルト実行環境が「V8 Runtime」というものに変わっていました。

 スクリプトエディタを開くと以下のような表示が出るようになっています。
f:id:rikoubou:20200317173402p:plain

 色々新しい書き方になっていたりするようなのですが、自分の環境でV8 Runtimeで実行してみるとhtmlからGASのスクリプト呼び出しができないようでした。
 これがバグなのか記述方法が別にあるのかはわかりませんが、V8 Runtimeで動かない場合は先に記述した方法で無効にした方がいいかもしれません。


・参考資料