-
-
Save mrkrndvs/a2c8ff518b16e9188338cb809e06ccf1 to your computer and use it in GitHub Desktop.
/* | |
* script to export data of the named sheet as an individual csv files | |
* sheet downloaded to Google Drive and then downloaded as a CSV file | |
* file named according to the name of the sheet | |
* original author: Michael Derazon (https://gist.github.com/mderazon/9655893) | |
*/ | |
function onOpen() { | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var csvMenuEntries = [{name: "Download Primary Time File", functionName: "saveAsCSV"}]; | |
ss.addMenu("Creating a Timetable", csvMenuEntries); | |
}; | |
function saveAsCSV() { | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getSheetByName('Primary Time'); | |
// create a folder from the name of the spreadsheet | |
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime()); | |
// append ".csv" extension to the sheet name | |
fileName = sheet.getName() + ".csv"; | |
// convert all available sheet data to csv format | |
var csvFile = convertRangeToCsvFile_(fileName, sheet); | |
// create a file in the Docs List with the given name and the csv data | |
var file = folder.createFile(fileName, csvFile); | |
//File downlaod | |
var downloadURL = file.getDownloadUrl().slice(0, -8); | |
showurl(downloadURL); | |
} | |
function showurl(downloadURL) { | |
var app = UiApp.createApplication().setHeight('60').setWidth('150'); | |
//Change what the popup says here | |
app.setTitle("Your timetable CSV is ready!"); | |
var panel = app.createPopupPanel() | |
//Change what the download button says here | |
var link = app.createAnchor('Click here to download', downloadURL); | |
panel.add(link); | |
app.add(panel); | |
var doc = SpreadsheetApp.getActive(); | |
doc.show(app); | |
} | |
function convertRangeToCsvFile_(csvFileName, sheet) { | |
// get available data range in the spreadsheet | |
var activeRange = sheet.getDataRange(); | |
try { | |
var data = activeRange.getValues(); | |
var csvFile = undefined; | |
// loop through the data in the range and build a string with the csv data | |
if (data.length > 1) { | |
var csv = ""; | |
for (var row = 0; row < data.length; row++) { | |
for (var col = 0; col < data[row].length; col++) { | |
if (data[row][col].toString().indexOf(",") != -1) { | |
data[row][col] = "\"" + data[row][col] + "\""; | |
} | |
} | |
// join each row's columns | |
// add a carriage return to end of each row, except for the last one | |
if (row < data.length-1) { | |
csv += data[row].join(",") + "\r\n"; | |
} | |
else { | |
csv += data[row]; | |
} | |
} | |
csvFile = csv; | |
} | |
return csvFile; | |
} | |
catch(err) { | |
Logger.log(err); | |
Browser.msgBox(err); | |
} | |
} |
@debruine: How do you make that work? I don't think Google Apps Script supports the R language.
Many thanks for @mrkrndvs for this valued share.
Many thanks too for @maedox for his response
Indeed, I got an error on the csv file generated.
In france the decimal is a comma.
But in the generated csv with getValues() function, the commas was remplaced by points.
Now with getDisplayValues() all is ok.
Thanks @mrkrndvs, this is great!
I'm having some problems with the function "onOpen"
Exception: Cannot call SpreadsheetApp.newMenu() from this context.
Can anyeone help me?
@Matt-McDonald-AS: That's because the CSV formatting code above isn't correct (it only checks for commas) - but there's more things to take into account:
- Quotes themselves must be escaped (double them -> " becomes "")
- Commas must be escaped (put string in quotes)
- New lines must be escaped (put string in quotes)
- Basically, all the values should be quoted, just to be safe.
I've updated the function to the following, and it works great:
function convertRangeToCsvFile_(csvFileName, sheet) { try { var data = sheet.getDataRange().getDisplayValues(); if (data.length > 1) { var rows = []; data.forEach(row => { var cols = []; row.forEach(col => { cols.push(`"${col.replace(/"/g, '""')}"`); }); rows.push(cols.join(',')); }); return rows.join('\n'); } } catch(err) { Logger.log(err); Browser.msgBox(err); } }
I'd rather recommend keeping the original code to keep the split functionality, but else a good improvement.
`function convertRangeToCsvFile_(sheet, rowsPerFile) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFiles = [];
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = (`"${data[row][col].replace(/"/g, '""')}"`) ; // modification of original code
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
if ((row + 1) % rowsPerFile === 0) {
csvFiles.push(csv);
csv = "";
}
}
}
// If there are remainders that doesnt reach the number of files needed.
// It will add another file, containing all remainder rows there.
// 10010 rows / 20 files = 10 rows excess
// 21st file will contain those 10 rows excess
// No excess means no 21st file
if(csv) {
csvFiles.push(csv);
}
return csvFiles;
}
catch(err) {
Logger.log(err);
}
}
`
This was great, thank you!
@gabrielgz92 I got it to work by replacing the showurl function with this:
function showurl(downloadURL) { //Change what the download button says here var link = HtmlService.createHtmlOutput('<a href="' + downloadURL + '">Click here to download</a>'); SpreadsheetApp.getUi().showModalDialog(link, 'Your CSV file is ready!'); }
This helped a TON. Thank you for this update! Worked perfect.
Hello, in my case I got a correct downloadURL but only working if I manually introduce it to the browser. However if url is called within the Apps Script (showModalDialog()) I got initial 303
status redirection followed up 18 302
status redirection since I end up with ERR_TOO_MANY_REDIRECTS
. Any clue?
- Folder is created OK
- Csv file is created OK
- URL file is created OK
- By changing folder permissions is not working aswell.
Other approach I did--> If I just copy the GET request from manually get
File > Download > CSV
in the browser works but within the dialog got this error:
Thanks!
Lines 53-72 could be simplified a little: