Initiate a download from google apps script
Solution 1:
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 :-)
Solution 2:
OP's answer is deprecated (in 2021), so I made a more general purpose one based on it.
Apologies it requires 2 files in the Apps Script instead of just 1 - Google be like that.
Code.gs
:
// Runs when the spreadsheet starts, adds a tab at the top
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Script Menu')
.addItem('Download a file!', 'dlFile')
.addToUi();
}
// Run when you click "Download a file!"
function dlFile() {
let file = DriveApp.getRootFolder().createFile('Hi.txt', 'Hello, world!');
// Create little HTML popup with the URL of the download
let htmlTemplate = HtmlService.createTemplateFromFile('Download.html');
htmlTemplate.dataFromServerTemplate = { url: file.getDownloadUrl() };
let html = htmlTemplate
.evaluate()
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Download');
};
Download.html
:
<!DOCTYPE html>
<html>
<head>
<script>
let data = <?!= JSON.stringify(dataFromServerTemplate) ?>; // Stores the data directly in the javascript code
function downloadFile() {
document.getElementById("dlBtn").innerText = "Downloading..";
window.open(data.url, '_blank');
document.getElementById("dlBtn").disabled = true;
}
</script>
</head>
<body>
<button id="dlBtn" onclick="downloadFile()">Download</button>
</body>
</html>