With the below code my goal is to extract a sheet from the Google sheet file in CSV format. However, when I want to convert the , to ; the following error message appears:
r.join is not a function
Could you please help me to solve this problem.
Also, do you think it is possible to download this new file directly to the desktop of the computer ?
function sheetToCsv(){
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "Int_Module";
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name)
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv"
var url = "https://docs.google.com/spreadsheets/d/"+ params
var result = UrlFetchApp.fetch(url, requestData);
var newfile = [result].map(r => r.join(";")).join("\n");
newfile.createFile(fileName, outputData, MimeType.PLAIN_TEXT);
}
I understand that there is 2 questions ... how to produce CSV file with semi-colon, and how to download the file directly to your PC.
1- To produce the csv content, try
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var sep = ';'
const content = sh.getDataRange().getValues().reduce((s, r) => s += r.map(c => c + sep).join("") + '\n', "")
2- To download, you will have to go through an html page.
Try this for both needs
function downloadMyCSVFile() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var sep = ';'
const content = sh.getDataRange().getValues().reduce((s, r) => s += r.map(c => c + sep).join("") + '\n', "")
var html = HtmlService.createHtmlOutput(`
<html><body onload="document.getElementById('dwn-btn').click()">
<textarea id="text-val" rows="10" style="display:none;">${content}</textarea>
<input type="button" id="dwn-btn" value="Download text file" style="display:none;"/>
<script>
window.close = function(){window.setTimeout(function(){google.script.host.close()},100)}
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
document.getElementById("dwn-btn").addEventListener("click", function(){
var text = document.getElementById("text-val").value;
var filename = "${sh.getName()}.csv";
download(filename, text);
close();
}, false);
</script>
</body></html>
`)
.setWidth(250).setHeight(100);
SpreadsheetApp.getUi().showModalDialog(html, "Downloading ...");
}
Trying to alter the following script to prompt for an email address. I was able to load this as an add-on in Google sheets and it works fine but I want to be able to change the "To" address each time I run it. Is there any way to force some sort of prompt so that I can input the email address on each run?
function onOpen() {
// Try New Google Sheets method
try{
var ui = SpreadsheetApp.getUi();
ui.createMenu('SendMail')
.addItem('Send Report', 'getGoogleSpreadsheetAsExcel')
.addToUi();
}
// Log the error
catch (e){Logger.log(e)}
}
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=csv";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(ss.getName() + ".csv");
MailApp.sendEmail("xxxxxx#gmail.com", "Stock report of today", "The XLSX file is attached", {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
}
All you need to do is get the UI of the spreadsheet and send a prompt then run it through an if statement to make sure the correct button is pressed, try the below:
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=csv";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(ss.getName() + ".csv");
var ui = SpreadsheetApp.getUi();
var prompt = ui.prompt('Enter email address:', '',ui.ButtonSet.OK_CANCEL);
if (prompt.getSelectedButton() == 'OK') {
var mail = prompt.getResponseText();
MailApp.sendEmail(mail, "Stock report of today", "The XLSX file is attached", {attachments: [blob]});
}
} catch (f) {
Logger.log(f.toString());
}
}
The code prompts for an email address:
var prompt = ui.prompt('Enter email address:', '',ui.ButtonSet.OK_CANCEL);
Then runs through a quick if statement to make sure the button pressed is 'OK', if it's cancelled it'll do nothing.
if (prompt.getSelectedButton() == 'OK') {
var mail = prompt.getResponseText();
MailApp.sendEmail(mail, "Stock report of today", "The XLSX file is attached", {attachments: [blob]});
}
As you can see, var mail is used in the sendEmail(), meaning it'll use whatever you entered as your email address as the recipient of your email.
I have an HTML form which contains email addresses from various suppliers. I am creating a kind of mail merge function so I can send all the contacts a personalised email when the form is submitted. Here is my .gs file:
function sendEmail(form) {
const sSheet = SpreadsheetApp.getActiveSpreadsheet();
const file = DriveApp.getFileById(sSheet.getId());
const documentUrl = file.getUrl();
/* var toEmail = form.toAddress;
var ccEmail = form.ccAddress;
var fromEmail = "****#*****.com";
var subject = form.subject;
var message = form.message; */
var toEmail = "";
var fromEmail = "****#*****.com";
var message = "";
var hotelAddresses = [
form.toAddress1,
form.toAddress2,
form.toAddress3,
form.toAddress4,
form.toAddress5,
form.toAddress6,
form.toAddress7,
form.toAddress8,
form.toAddress9,
form.toAddress10,
form.toAddress11,
form.toAddress12,
form.toAddress13,
form.toAddress14,
form.toAddress15,
form.toAddress16,
form.toAddress17,
form.toAddress18,
form.toAddress19,
form.toAddress20,
form.toAddress21,
form.toAddress22,
form.toAddress23,
form.toAddress24,
form.toAddress25,
form.toAddress26,
form.toAddress27,
form.toAddress28,
form.toAddress29,
form.toAddress30,
form.toAddress31,
form.toAddress32,
form.toAddress33,
];
var contactNames = [
form.contactName1,
form.contactName2,
form.contactName3,
form.contactName4,
form.contactName5,
form.contactName6,
form.contactName7,
form.contactName8,
form.contactName9,
form.contactName10,
form.contactName11,
form.contactName12,
form.contactName13,
form.contactName14,
form.contactName15,
form.contactName16,
form.contactName17,
form.contactName18,
form.contactName19,
form.contactName20,
form.contactName21,
form.contactName22,
form.contactName23,
form.contactName24,
form.contactName25,
form.contactName26,
form.contactName27,
form.contactName28,
form.contactName29,
form.contactName30,
form.contactName31,
form.contactName32,
form.contactName33,
];
var days = [
form.day1,
form.day2,
form.day3,
form.day4,
form.day5,
form.day6,
form.day7,
form.day8,
form.day9,
form.day10,
form.day11,
form.day12,
form.day13,
form.day14,
form.day15,
form.day16,
form.day17,
form.day18,
form.day19,
form.day20,
form.day21,
form.day22,
form.day23,
form.day24,
form.day25,
form.day26,
form.day27,
form.day28,
form.day29,
form.day30,
form.day31,
form.day32,
form.day33,
];
var dates = [
form.date1,
form.date2,
form.date3,
form.date4,
form.date5,
form.date6,
form.date7,
form.date8,
form.date9,
form.date10,
form.date11,
form.date12,
form.date13,
form.date14,
form.date15,
form.date16,
form.date17,
form.date18,
form.date19,
form.date20,
form.date21,
form.date22,
form.date23,
form.date24,
form.date25,
form.date26,
form.date27,
form.date28,
form.date29,
form.date30,
form.date31,
form.date32,
form.date33,
];
var times = [
form.time1,
form.time2,
form.time3,
form.time4,
form.time5,
form.time6,
form.time7,
form.time8,
form.time9,
form.time10,
form.time11,
form.time12,
form.time13,
form.time14,
form.time15,
form.time16,
form.time17,
form.time18,
form.time19,
form.time20,
form.time21,
form.time22,
form.time23,
form.time24,
form.time25,
form.time26,
form.time27,
form.time28,
form.time29,
form.time30,
form.time31,
form.time32,
form.time33,
];
var additionalInfo = [
form.additional1,
form.additional2,
form.additional3,
form.additional4,
form.additional5,
form.additional6,
form.additional7,
form.additional8,
form.additional9,
form.additional10,
form.additional11,
form.additional12,
form.additional3,
form.additional14,
form.additional15,
form.additional16,
form.additional17,
form.additional18,
form.additional19,
form.additional20,
form.additional21,
form.additional22,
form.additional23,
form.additional24,
form.additional25,
form.additional26,
form.additional27,
form.additional28,
form.additional29,
form.additional30,
form.additional31,
form.additional32,
form.additional33,
];
for(var i = 0; i<times.length; i++){
var subject = "Meeting - " + days[i] + ", " + dates[i] + " at " + times[i];
toEmail = hotelAddresses[i];
message = "Dear " + contactNames[i] + ","
+"<br><br>"+
"Please confirm the meeting on " + days[i] + " " + dates[i] + " at " + times[i] + "." + "<br>" + "<br>" +
additionalInfo[i] +
" If you could kindly let me know if you are able to confirm that would be great." + "<br>" + "<br>" +
"Many thanks and I look forward to hearing from you soon." + "<br>" + "<br>" +
"Yours sincerely," + "<br>" + "<br>" +
form.yourName + "<br>" + "<br>"
+ "<em><b>" + form.yourPosition + "</b></em> <br><br>" +
"<span style='color:#0e216d'><b> Company name. </b>" + "<br>" +
GmailApp.sendEmail(
toEmail, // recipient
subject, // subject
'test', { // body
htmlBody: message // advanced options
}
);
}
}
It works fine except that sometimes the input fields for email will be blank, in which case I need the script to ignore that supplier and continue to run. At the moment it is obviously hitting the empty input and stopping the execution.
I presume I need a conditional statement of sorts... something along the lines of if(hotelAddresses[i] != null) {}
But I cannot work out where to insert this...
Additional: 31 Aug 18
For the HTML I have a series of objects (33 in total) that are all set up like this:
<input type="checkbox" id="check1" class="check" checked>
<input type="text" id="name1" class="contactNameInput" name="toAddress1">
<input type="text" id="contactName1" class="contactNameInput mailName" name="contactName1">
<input type="text" id="time1" class="contactNameInput hidden mailTime" name="time1">
<input type="text" id="day1" class="contactNameInput hidden mailDay" name="day1">
<input type="text" id="date1" class="contactNameInput hidden mailDate" name="date1">
<textarea class="additional contactNameInput" id="additional1" name="additional1" placeholder="Additional requests..."></textarea>
<div class="preview1"></div>
You want to separate the cases with and without hotelAddresses[i] using a script like if(hotelAddresses[i] != null) {}. When my understanding is correct, how about this modification?
Modification points:
Do you want to add after "<span style='color:#0e216d'><b> Company name. </b>" + "<br>" +? In the current script, it's "<span style='color:#0e216d'><b> Company name. </b>" + "<br>" + GmailApp.sendEmail(...). If you want to add more strings, please put them. If you don't want to add, please remove the last +.
I think that the script of if(hotelAddresses[i] != null) {} can be used in the for loop.
The script which reflected above is as follows.
Modified script:
In this modified script, the script of for loop was modified.
for(var i = 0; i<times.length; i++) {
var toEmail = hotelAddresses[i];
if (toEmail) {
var subject = "subject";
var message = "messages";
GmailApp.sendEmail(toEmail, subject, 'test', {htmlBody: message});
} else {
// do something
}
}
Note:
In this modified script, subject and message are replaced by "subject" and "messages", respectively. So please modify them for your situation.
If you want to do something when hotelAddresses[i] is null, please modify // do something.
If you don't want to do something when hotelAddresses[i] is null, please remove else {}.
If I misunderstand your question, please tell me. I would like to modify it.