Search code examples
google-sheetsgoogle-apps-scriptgoogle-drive-api

Initiate a download


I added a new menu item to my spreadsheet using google apps script. This menu item creates a file, but I'd like for it to initiate the download of the file after creating it.

Is this possible?

Remember, this is not a web app, but a menu item in my spreadsheet.

Edit:

Thanks to Serge insas' suggestion, the following simple script works perfectly, and opens a download window with the link I need:

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var csvMenuEntries = [ {name: "Zip all CSVs", functionName: "saveAsCSV"} ];
  ss.addMenu("CSV", csvMenuEntries);
};

function saveAsCSV() {
  var folder = createCSVs(); // creates a folder with CSV for each Sheet
  var zipFile = zipCSVs(folder, "DI.zip"); // creates a zip of all CSVs in folder
  
  var ui = UiApp.createApplication().setTitle("Download");
  var p = ui.createVerticalPanel();
  ui.add(p);
  p.add(ui.createAnchor("Download", zipFile.getDownloadUrl()));
  SpreadsheetApp.getActive().show(ui)
}

Solution

  • EDIT : read the comments below, Zig Mandel is perfectly right when he points out the limitations of the "complicated" version, it was really a simple (and fun) exercice to show other methods.


    I think you'll have to use an intermediate Ui as a popup to confirm the download. After that there are 2 possible ways that I know, one is very simple and the other is quite cumbersome, make your choice, the code below shows both of them.

    note : to use the complicated one you need to deploy your app (ie save a version and deploy as webapp), for the simple one just use it "as it is". (I show the simple in the code comments).

    The code :

    function onOpen() {
      var menuEntries = [ {name: "test download", functionName: "downloadFile"}
                         ];
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      sheet.addMenu("Utils",menuEntries);
    }
    
    function downloadFile(){
      var file = DriveApp.createFile('test file', 'Some content in this file to test it');
      var fileID = file.getId();
      var fileName = file.getName();
      var ui = UiApp.createApplication().setTitle('Download');
      var url = ScriptApp.getService().getUrl()+'?&ID='+fileID+'&name='+fileName;
      var p = ui.createVerticalPanel();
      ui.add(p);
      p.add(ui.createAnchor('click to download', url));
      p.add(ui.createAnchor('or use this link ',file.getDownloadUrl()));// this is the simple one, just get the file you created and use getDownloadUrl()
      SpreadsheetApp.getActive().show(ui)
    }
    
    function doGet(e){
      var fileId = e.parameter.ID;
      var fileName = e.parameter.name;
      var fileString = DocsList.getFileById(fileId).getContentAsString();
      return ContentService.createTextOutput(fileString).downloadAsFile(fileName);
    }
    

    PS : I had some fun writing this, the "complicated version" is really funny imho :-)