SoftwareTester
SoftwareTester

Reputation: 1090

Converting google spreadsheet to XLSX or ODS using GAS

I want to convert a few google spreadsheets to Excel (xlsx preferred).
I've read several threads about how to achieve this, but I can't get it running.
Amongst the threads I've read are Google Apps Script: Save Spreadsheet as ODS for Local Backup and Google apps script to email google spreadsheet excel version

In order to stay close to code I've found AND get more info about why it doesn't work, I modified code I found such that it just handles a few files and also try-catch has been removed.

****************** Not working code **************
function contentODS(key, gid) 
{
   var file = DocsList.getFileById(key); 

   var fetchParameters = oAuth();

   var url = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=" + key + "&gid=" + gid + "&exportFormat=ods";
   var response = UrlFetchApp.fetch(url, fetchParameters);

   var fileBlob = response.getBlob();  
   return fileBlob;
}

function oAuth()
{ // https://stackoverflow.com/questions/24493203/google-apps-script-save-spreadsheet-as-ods-for-local-backup
  var oauthConfig = UrlFetchApp.addOAuthService("spreadsheets");
  var scope = "https://spreadsheets.google.com/feeds" 
  oauthConfig.setConsumerKey("anonymous");
  oauthConfig.setConsumerSecret("anonymous");
  oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=" + scope);
  oauthConfig.setAuthorizationUrl("https://accounts.google.com/OAuthAuthorizeToken");    
  oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");   

  var requestData =
  {
    "oAuthServiceName":   "spreadsheets",
    "oAuthUseToken":      "always",
    "muteHttpExceptions": true,
    "method":             "DELETE",
  };
  return requestData;
}

function eachSheet(key, newFolderId)
{
  var ss = SpreadsheetApp.openById(key);
  var ssId = ss.getId();
  var ssName = ss.getName();
  var howManySheets = ss.getNumSheets();

  for (var sheetIndex=0; sheetIndex < howManySheets; sheetIndex++)
  {   
     var activeSheet = ss.getSheets()[sheetIndex];
     var activeName = activeSheet.getName();
     var activeId = activeSheet.getSheetId();
     var time = new Date();
     var fileName = time + " Backup: " + ssName + " " + activeName + ".ods";
     var blob = contentODS(ssId, activeId);
     var folder = DocsList.getFolderById(newFolderId);  
     folder.createFile(blob).rename(fileName);
   } 
}

function backUpMaker()
{
  var backupDirectory = 'Backup';
  var folders = DriveApp.getRootFolder().getFoldersByName(backupDirectory);
  var backupFolderId = undefined;
  if (folders.hasNext()) backupFolderId = folders.next().getId();
  else return;  // File doe not exist

  var timeNow = new Date();  
  var newFolder = DocsList.createFolder(timeNow);
  var newFolderId = newFolder.getId();
  newFolder.addToFolder(DocsList.getFolderById(backupFolderId));
  newFolder.removeFromFolder(DocsList.getRootFolder());
  var sheets = DriveApp.getFilesByType(MimeType.GOOGLE_SHEETS);
  while (sheets.hasNext())
  {
    var sheet = sheets.next();
    var name = sheet.getName();

    var filesToSave = [ 'My-Agenda', 'My-Kalender' ];
    var numFiles = filesToSave.length;

    for (var i=0; i<numFiles; i++)
    {
       if (name == filesToSave[i])
       {
          var sheetId = sheet.getId();
          var csv = eachSheet(sheetId, newFolderId); 
          break;
       }  
    }   
  }
  var backupFolder = DocsList.getFolderById(backupFolderId);
  var newFiles = newFolder.getFiles();
  var numFiles = newFiles.length;

  if (numFiles > 0)
  {
     var nameZipFile = timeNow + '.zip';
     backupFolder.createFile(Utilities.zip(newFiles, nameZipFile));
  } 

  newFolder.setTrashed(true);
}

Running backupmaker fails at var response = UrlFetchApp.fetch(url, fetchParameters);
and indicates verification for service spreadsheets failed

Waht should I do to make it work.

Upvotes: 1

Views: 3264

Answers (1)

Eric Koleda
Eric Koleda

Reputation: 12671

You can use the Advanced Drive Service to get the export URL and use the script's OAuth2 token to download the file.

function exportAsExcel(spreadsheetId) {
  var file = Drive.Files.get(spreadsheetId);
  var url = file.exportLinks['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
  var token = ScriptApp.getOAuthToken();
  var response = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' +  token
    }
  });
  return response.getBlob();
}

function test() {
  var spreadsheetId = 'SPREADSHEET ID HERE';
  DriveApp.createFile(exportAsExcel(spreadsheetId));
}

Upvotes: 4

Related Questions