Uploading Multiple Files with Split Asynchronous Processes and Resumable Upload in Google Spreadsheets

Gists

Overview

This sample script demonstrates uploading multiple files using split asynchronous processes with resumable upload. It leverages JavaScript and HTML within Google Spreadsheets.

Description

In my previous report, “Resumable Upload of Multiple Files with Asynchronous Process for Google Drive”, I presented an approach for uploading files asynchronously.

This script builds upon that concept, introducing a method for uploading multiple files with split asynchronous processes that utilize resumable upload.

Here’s the process breakdown:

  1. File Selection: Users select the files to be uploaded.
  2. Chunking: Each selected file is split into smaller chunks.
  3. Asynchronous Uploads per Chunk: Individual chunks from each file are uploaded asynchronously using resumable upload.
  4. Synchronous Chunk Processing: Chunks are processed synchronously within the script.

This approach enables uploading files through split asynchronous processes while leveraging resumable upload functionality.

Usage

1. Prepare Spreadsheet

Here, as a sample, Javascript and HTML are run on Google Spreadsheet. Please create a new Google Spreadsheet and open the script editor.

2. Enable Drive API

Please enable Drive API at Advanced Google services. Ref

3. Script

Please copy and paste the following Google Apps Script (code.gs) and HTML (index.html).

code.gs

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

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

index.html

<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@2.0.2/resumableupload_js.min.js"></script>
</script>
<script>
function run() {
  google.script.run.withSuccessHandler(accessToken => ResumableUploadForGoogleDrive(accessToken)).getAuth();
}


function upload({ accessToken, file, idx }) {
  return new Promise((resolve, reject) => {
    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_${idx}`;
      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,
        folderId: "root",
      };
      const ru = new ResumableUploadToGoogleDrive();
      ru.Do(resource, function (res, err) {
        if (err) {
          reject(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})`;
        }
        if (res.status == "Done") {
          resolve(res.result);
        }
        document.getElementById(id).innerText = msg;
      });
    };
  });
}


async function ResumableUploadForGoogleDrive(accessToken) {

  const n = 2; // You can adjust the chunk size. Default is 2.

  const f = document.getElementById("file");
  const files = [...f.files];
  const splitFiles = [...Array(Math.ceil(files.length / n))].map((_) => files.splice(0, n));
  for (let i = 0; i < splitFiles.length; i++) {
    const res = await Promise.all(splitFiles[i].map(async (file, j) => await upload({ accessToken, file, idx: `${i}_${j}` })));
    console.log(res);
  }
}
</script>
  • In this sample, the files are uploaded to the root folder. If you want to upload the files in the specific folder, please modify folderId: "root", to folderId: "###your folder ID###",.

  • In this sample, the chunk size is 2. So, the files are uploaded every 2 file. If you want to change this, please modify 2 of const n = 2; to your situation.

4. Testing

When this script is run, the following result is obtained.

References

 Share!