1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javascript で再開可能アップロードを使って大きなサイズのファイルを非同期で Google Drive へアップロードする

Posted at

背景と概要

大きなサイズのファイル(5 MB 以上あるいは 50 MB 以上)を Google Drive へアップロードしようとすると、再開可能アップロード(Resumable upload)のプロセスを行う必要があります。Javascript を使用してブラウザからファイルをアップロードするとき、多くの場合は公式のライブラリであるgoogle-api-javascript-clientを使用します。この場合、Google Docs ファイルの新規作成や 5 MB 以下のファイルをアップロードすることは可能ですが、この記事を書いた段階では再開可能アップロードを行うためのメソッドはまだ用意されていません。そこで、Javascript を使って大きなサイズのファイルを再開可能アップロードプロセスでアップロードするためのライブラリを作成しました。

ここでは、このライブラリを使用したサンプルとして、大きなサイズのファイル(100 MB)を 5 つ用意し、これを非同期で Google Drive へアップロードするスクリプトを紹介させていただきます。

ResumableUploadForGoogleDrive_js

ResumableUploadForGoogleDrive_js は、Drive API を使用してファイルを再開可能アップロードするための Javascript 用ライブラリです。リポジトリはこちらです。詳細な使用方法は、リポジトリをご覧ください。

使い方

1. スプレッドシートの作成

ここでは、スプレッドシートを作成し、スプレッドシート上へ開いたサイドバーでスクリプトを実行させます。そのため、最初にスプレッドシートを作成してください。作成後、スクリプトエディタを開いてください。

2. サンプルスクリプトをコピーペースト

Google Apps Script と HTML&Javascript の 2 種類のスクリプトを使用します。そのため、スクリプトエディタを開いた際、ファイル->新規作成->HTML ファイル として HTML ファイルを作成してください。ファイル名はindex.htmlです。

Google Apps Script: コード.gs

下記のスクリプトをコード.gsへコピーペーストします。

function main() {
  var html = HtmlService.createHtmlOutputFromFile("index");
  SpreadsheetApp.getUi().showSidebar(html);
}

function getAuth() {
  // DriveApp.createFile(blob) // This is used for adding the scope of "https://www.googleapis.com/auth/drive".
  return ScriptApp.getOAuthToken();
}

HTML: index.html

下記のスクリプトを作成したindex.htmlへコピーペーストします。ライブラリは、jsdelivr cdn を使ってロードしています。また、アクセストークンは Google Apps Script 側で取得しています。

<input type="file" id="file" multiple="true" />
<input type="button" onclick="run()" value="Upload" />
<div id="progress"></div>

<script src="https://cdn.jsdelivr.net/gh/tanaikech/ResumableUploadForGoogleDrive_js@master/resumableupload_js.min.js"></script>
<script>
  function run() {
    google.script.run
      .withSuccessHandler(accessToken =>
        ResumableUploadForGoogleDrive(accessToken)
      )
      .getAuth();
  }

  function ResumableUploadForGoogleDrive(accessToken) {
    const f = document.getElementById("file");
    [...f.files].forEach((file, i) => {
      let fr = new FileReader();
      fr.fileName = file.name;
      fr.fileSize = file.size;
      fr.fileType = file.type;
      fr.readAsArrayBuffer(file);
      fr.onload = e => {
        var id = "p" + ++i;
        var div = document.createElement("div");
        div.id = id;
        document.getElementById("progress").appendChild(div);
        document.getElementById(id).innerHTML = "Initializing.";
        const f = e.target;
        const resource = {
          fileName: f.fileName,
          fileSize: f.fileSize,
          fileType: f.fileType,
          fileBuffer: f.result,
          accessToken: accessToken
        };
        const ru = new ResumableUploadToGoogleDrive();
        ru.Do(resource, function(res, err) {
          if (err) {
            console.log(err);
            return;
          }
          console.log(res);
          let msg = "";
          if (res.status == "Uploading") {
            msg =
              Math.round(
                (res.progressNumber.current / res.progressNumber.end) * 100
              ) +
              "% (" +
              f.fileName +
              ")";
          } else {
            msg = res.status + " (" + f.fileName + ")";
          }
          document.getElementById(id).innerText = msg;
        });
      };
    });
  }
</script>

3. スクリプトの実行

スクリプトエディタから ファンクション main() を実行すると、スプレッドシート上へサイドバーが表示されます。ここでファイルを選択して Upload ボタンを押すと、ファイルがアップロードされます。下記はデモンストレーションの動画です。

20191021a-demo.gif

また、サンプルスクリプトのリポジトリはこちらです。

参考

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?