简体   繁体   中英

Avoiding exceeding execution time when recursively converting Google Sheets to Excel

I am working on a script to go through a series of folders in my Google Drive, make copies of the folder structure, and convert files contained in the folders to Excel or Word.

There are three possible options: Google Sheets files should be converted to Excel; Google Docs files to Word; and other files should be copied as-is.

I am using a recursive function to explore the file structure.

The script seems to work, but I am exceeding the allowable execution time. Analysing the Execution transcript, this would appear to be because of the ~2 seconds it takes to convert each Google file to an MS-Office file.

Can anyone suggest either:

  • a faster method of converting files?
  • a method for keeping track of where the recursive process is up to, so that I can pause and resume the process? (I'd also appreciate some advice on HOW to pause and resume the process ;-)

Apologies if this has been covered, I did spend some time searching to find answers to this, and I can see similar questions but not a solution that I can understand.

Code below.

function folderRecurse(folderToSearch, folderToSave){
  while (folderToSearch){ // the function has been passed a folder to search inside
    var searchFolderId = folderToSearch.getId(); // get the Id of the folder passed
    var currentFolder = DriveApp.getFolderById(searchFolderId); //open the search folder passed
    var newName = currentFolder.getName(); // get the name of the search folder passed
    var saveFolder = folderToSave.createFolder(newName);// make a copy of the search folder in the backup folder
    var subfolders = currentFolder.getFolders(); //get any subfolders of the folder passed
      while (subfolders.hasNext()){ // if there are subfolders, start again by passing the function the folder to search and the folder to save to
      var subfolder = subfolders.next();
      folderRecurse(subfolder, saveFolder);
    }
    // when there are no more folders left, deal with the files inside the folder
    var folderFiles = folderToSearch.getFiles();
    while (folderFiles.hasNext()){
      // get the file
      var thisFile = folderFiles.next();
      // get the file's name
      var thisFileName = thisFile.getName();
      //test the file type
      var fileType = thisFile.getMimeType();
      Logger.log(fileType);
      if (fileType == "application/vnd.google-apps.document"){ // this is a google doc-- save it as a word document
        //google docs to word method
      }
      else if (fileType == "application/vnd.google-apps.spreadsheet"){ // this is a spreadsheet -- save it as an excel file
        convertToXlsxAndSave(thisFile,saveFolder)
        Logger.log(thisFile.getName());
      }
      else { // save it as whatever kind of file it is
       thisFile.makeCopy(thisFile.getName(),saveFolder);
      }
    }
    return 0;
  }
  return 0;
}

function convertToXlsxAndSave(thisFile, saveFolder){

  //open the file as an excel sheet
  var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + thisFile.getId() + "&exportFormat=xlsx";

  // set parameters
  var params = {
      method      : "get",
      headers     : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
      muteHttpExceptions: true
    };

  // get the binary
  var blob = UrlFetchApp.fetch(url, params).getBlob();

  // name the binary with the fileName
  blob.setName(thisFile.getName() + ".xlsx");

  // save the binary into the proper folder
  saveFolder.createFile(blob);
}

function convertToDocxAndSave(thisFile, saveFolder){

  //open the file as a word doc sheet
  var url = "https://docs.google.com/feeds/download/documents/export/Export?id=" + thisFile.getId() + "&exportFormat=docx";

  // set parameters
  var params = {
      method      : "get",
      headers     : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
      muteHttpExceptions: true
    };

  // get the binary
  var blob = UrlFetchApp.fetch(url, params).getBlob();

  // name the binary with the fileName
  blob.setName(thisFile.getName() + ".docx");

  // save the binary into the proper folder
  saveFolder.createFile(blob);
}


function createMsOfficeVersions() {
  // this function works through the files in the folders enumerated below, and creates MS Office versions. Eg Google Sheets convert to Excel files, Google Docs to Word files. The files are stored in a folder for downloading to AC.

  // create a date-stamped folder within the backups folder

  var formattedDate = Utilities.formatDate(new Date(), "GMT+12", "dd MMMM yyyy");

  var backupLabel = "HAMP Survey MS Office backup versions " + formattedDate;

  // get the folder Ms Office versions
  var backupDir = DriveApp.getFolderById('XXXXXXX');

  // make a new date-stamped folder to save the files into
  var thisBackup = backupDir.createFolder(backupLabel);

  // get the Survey 2015-2016 folder and subfolders
  var hampSurveyFolder = DriveApp.getFolderById('XXXXXXXXX');

  // loop through all the folders. For each, create a new folder inside the backup folder, grab all the files, test if they are docs or spreadsheets, copy to the new folder. if they are neither, copy as is.
  folderRecurse(hampSurveyFolder,thisBackup);

}

If the Google Drive folder has a large number of files, the script is likely to timeout. You should instead use a time-based trigger that runs every 10 minutes and converts the files while the file iterator should be stored as a property to continue from where it left off earlier.

function myFunction() {

  var props = PropertiesService.getScriptProperties();
  var token = props.getProperty('TOKEN');
  var files = continuationToken ? DriveApp.continueFileIterator(token) : DriveApp.getFiles();
  var start = Date.now();

  while (files.hasNext() && (Date.now() - start < 5*60*1000)) {
    var file = files.next();    
    // convert files    
  }

  if (files.hasNext()) {
    props.setProperty("TOKEN", files.getContinuationToken());
  } else {
    props.deleteProperty("TOKEN");
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM