I believe your goal as follow.
- You want to run the script from the custom menu.
- You want to download the active sheet as a file including a JSON data.
- The sample JSON data is as follows.
[{"a1": "a2", "b1": "b2"},{"a1": "a3", "b1": "b3"},,,]
In this case, in order to download a file, it is required to use Javascript. For this, in this answer, a dialog is used. So the flow of this sample script is as follows.
- Run the script from the custom menu.
- A dialog is opened.
- Javascript is run on the dialog, and the file is downloaded.
- The dialog is closed.
When above flow is reflected to a script, it becomes as follows.
Sample script:
Please copy and paste the following script to the script editor and run onOpen or reopen the Spreadsheet. By this, the custom menu is created.
Google Apps Script side: Code.gs
Please copy and paste the following script to the script editor as the Google Apps Script.
function onOpen() {
SpreadsheetApp.getUi().createMenu('Custom Menu').addItem('Export to JSON', 'download').addToUi();
}
function download() {
const html = HtmlService.createHtmlOutputFromFile("index");
SpreadsheetApp.getUi().showModalDialog(html, "sample");
}
function downloadFile() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const [header, ...values] = sheet.getDataRange().getValues();
const obj = values.map(r => r.reduce((o, c, j) => Object.assign(o, {[header[j]]: c}), {}));
const filename = `${sheet.getSheetName()}.txt`;
const blob = Utilities.newBlob(JSON.stringify(obj), MimeType.PLAIN_TEXT, filename);
return {data: `data:${MimeType.PLAIN_TEXT};base64,${Utilities.base64Encode(blob.getBytes())}`, filename: filename};
}
HTML&Javascript side: index.html
Please copy and paste the following script to the script editor as the HTML.
<script>
google.script.run
.withSuccessHandler(({ data, filename }) => {
if (data && filename) {
const a = document.createElement("a");
document.body.appendChild(a);
a.download = filename;
a.href = data;
a.click();
}
google.script.host.close();
})
.downloadFile();
</script>
References: