Nothing similar and a not-so-frequent Apps Script question - google-apps-script

Through trial and error I modified the below line of code to print the range B4:I59. Can someone help me to understand what the code says and/or how do I read it?
Original code
var printRange = '&c1=0' + '&r1=0' + '&c2=7' + '&r2='+row2; // B2:APn
Modified Code
var printRange = '&c1=1' + '&r1=2' + '&c2=9' + '&r2='+row2; // B4:I59
This is my whole code:
//* Print Extentions
function printPdf() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var gid = sheet.getSheetId();
var pdfOpts = '&size=A4&fzr=false&landscape=false&fith=true&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=false&gid='+gid;
var row2 = 59;
var printRange = '&c1=1' + '&r1=2' + '&c2=9' + '&r2='+row2; // B4:I59
var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + pdfOpts + printRange;
var app = UiApp.createApplication().setWidth(200).setHeight(50);
app.setTitle('Print Extentions List');
var link = app.createAnchor('Download PDF', url).setTarget('_new');
app.add(link);
ss.show(app);
}
The code works

In the line:
var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + pdfOpts + printRange;
You are defining a URL that will allow you to export the given spreadsheet as a PDF using the specified options. The & symbols separate arguments you are passing into the URL.
This document gives a nice description of the parameters you are using. According to that document:
//r1=Start Row number - 1 row 1 would be 0 , row 15 wold be 14
//c1=Start Column number - 1 column 1 would be 0, column 8 would be 7
//r2=End Row number
//c2=End Column number

Related

PDF attachment corrupted

After the issue with GmailApp declaratrion has benn resolved, I'm stuck now with a new problem, regarding my pdf attachment which is unreadable.
Prior to this bug, the pdf attachment was working perfectly.
I'm doubting that the var "blobresponse" or "pdfOpts" are the source of the problem, but maybe I'm wrong.
What's going wrong with the script ? Could you please explain me ?
Here is a reproducible example
function emailAsPDF() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Recherche"));
var sheet = ss.getActiveSheet();
var gid = sheet.getSheetId();
var pdfOpts =
'exportFormat=pdf&format=pdf'+ // export as pdf
'&size=0' + // paper size letter / You can use A4 or legal
'&portrait=false' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=true' + // hide optional headers and footers
'&pagenumbers=true&gridlines=false' + // hide page numbers and gridlines
'&horizontal_alignment=CENTER&vertical_alignment=CENTER' +
'&fzr=true' + // do not repeat row headers (frozen rows) on each page
'&attachment=false' +
gid;
// '&size=0&fzr=true&portrait=false&fitw=true&gridlines=false&printtitle=true&sheetnames=false&pagenumbers=true&attachment=false&gid='+gid;
SourceSS = SpreadsheetApp.getActive();
var SourceSheet = SourceSS.getSheetByName("Recherche");
var url = 'https://docs.google.com/spreadsheets/d/' + SourceSS.getId().replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;
//var url = 'https://docs.google.com/spreadsheets/d/'.replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;
var token = ScriptApp.getOAuthToken();
//var options = {
//options = {muteHttpExceptions: true};
//var options = {
var blobresponse = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token,
},
muteHttpExceptions: true}
);
//options);
var CandidateName = ss.getRangeByName("Nom.Candidat").getValue();
var blob=blobresponse.getBlob().setName(ss.getName() + " - " + CandidateName +".pdf" );
var emailAddress = Session.getActiveUser().getEmail();
var signature = Gmail.Users.Settings.SendAs.get("me", emailAddress).signature;
var mess = "Voulez-vous envoyer votre rapport à l'adresse : " + emailAddress;
var ans= Browser.msgBox("Courriel", mess, Browser.Buttons.YES_NO);
if (ans===Browser.Buttons.NO){return;}
var mess="Votre rapport a été envoyé à l'adresse : " + emailAddress;
//var ss=SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Recherche");
var data = ss.getSheetByName("Données");
const corps = data.getRange("A24:E27").getValues();
const htmlTemplate = HtmlService.createTemplateFromFile("HtmlSigTemplate");
htmlTemplate.corps = corps;
var emailSubject = "Vérifications pré-emploi complétées" +" - "+ CandidateName;
const htmlForEmail = htmlTemplate.evaluate().getContent() + "--" + "<br>" + signature;
//console.log(htmlForEmail);
GmailApp.sendEmail(
emailAddress,
emailSubject,
corps,
{htmlBody: htmlForEmail,
attachments:[blob]});
Browser.msgBox("Courriel", mess, Browser.Buttons.OK);
}
function parentFolder() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var file = DriveApp.getFileById(ss.getId());
var ParentFolder= file.getParents();
while ( ParentFolder.hasNext() ) {
var folder = ParentFolder.next();
folderID=folder.getId();
Logger.log(folderID);
}
return folderID;
}
I found the culprit after a long and painful research. You notice that the last line in the variable pdfOpts was missing a little detail
Old code:
var pdfOpts =
'exportFormat=pdf&format=pdf'+ // export as pdf
'&size=0' + // paper size letter / You can use A4 or legal
'&portrait=false' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=true' + // hide optional headers and footers
'&pagenumbers=true&gridlines=false' + // hide page numbers and gridlines
'&horizontal_alignment=CENTER&vertical_alignment=CENTER' +
'&fzr=true' + // do not repeat row headers (frozen rows) on each page
'&attachment=false' +
gid;
New code:
const pdfOpts = '&top_margin=0.30&bottom_margin=0.30&left_margin=0.25&right_margin=0.25'
+'&size=LETTER' // paper size letter / You can use A4 or legal
+'&portrait=false' // orientation portal, use false for landscape
+'&fitw=true' // fit to page width false, to get the actual size
+'&sheetnames=false' // hide optional headers
+'&printtitle=true' //and footers
+'&pagenumbers=true' // hide page numbers
+'&gridlines=false' //and gridlines
+'&horizontal_alignment=CENTER'
+'&vertical_alignment=CENTER'
+'&fzr=true' // do not repeat row headers (frozen rows) on each page
+'&attachment=false'
+'&gid='+gid;
The code has several issues. I suggest you to start to cleaning up your script by removing the redundant statements and adopting better modern JavaScript practices. I.E.
Instead of var use const or let. Old Google Apps Script code used var all the time because const and let were not supported. The current Google Apps Script default runtime does it.
Related
What's the difference between using "let" and "var"?
v8 JavaScript performance implications of const, let, and var?
Instead of
ss.setActiveSheet(ss.getSheetByName("Recherche"));
var sheet = ss.getActiveSheet();
use
const sheet = ss.getSheetByName("Recherche");
Instead of
SourceSS = SpreadsheetApp.getActive();
var SourceSheet = SourceSS.getSheetByName("Recherche");
var url = 'https://docs.google.com/spreadsheets/d/' + SourceSS.getId().replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;
use
const url = 'https://docs.google.com/spreadsheets/d/' + ss.getId() + '/export?exportformat=pdf&format=pdf' + pdfOpts;
NOTES:
getId() returns the spreadsheet id, it doesn't includes edit.
It not necessary to declared new variables for the spreadsheet and sheet to be exported as PDF as the ones that were previously declared have the required objects.
Also you might find helpful to review previous questions related to the use of UrlFetchApp to create a PDF like the following:
Generate PDF of only one sheet of my spreadsheet
Exporting Google Sheet as PDF with Custom Headers or Footers in Google Apps Script
Can no longer produce PDF from Google Sheets spreadsheet for some of the users

screenshot of Google spreadsheet range [duplicate]

This question already has answers here:
Export a range as a PDF in Google Apps Script
(3 answers)
Closed 6 months ago.
I'm trying to take a screenshot of a range of cells in Google spreadsheet every time a value changes in that range and save the screenshot in a URL or in my drive as .jpg, .png or pdf
I was able to find something similar for taking screenshots of charts but wasn't able to modify the script successfully for this case, has anyone done something similar
Take this as a reference, modify if needed:
Code:
function exportPdf(e) {
var spreadsheet = e.source;
var sheet = spreadsheet.getActiveSheet();
var range = e.range;
// sample dimension to be checked is B2:E5
var checkDimension = {
startingRow: 2,
startingColumn: 2,
endingRow: 5,
endingColumn: 5
};
// range should be within checkDimension and Sheet1
if(sheet.getSheetName() == 'Sheet1' &&
range.getRow() >= checkDimension.startingRow &&
range.getLastRow() <= checkDimension.endingRow &&
range.getColumn() >= checkDimension.startingColumn &&
range.getLastColumn() <= checkDimension.endingColumn) {
var spreadsheetId = spreadsheet.getId();
var sheetId = sheet.getSheetId();
var exportRange = "B2:E5";
var urlString = 'export?exportFormat=pdf&format=pdf' +
'&gid=' + sheetId + '&id=' + spreadsheetId +
'&range=' + exportRange +
'&size=A4' + // paper size
'&portrait=true'; // orientation, false for landscape
// See https://webapps.stackexchange.com/questions/130654/all-google-docs-url-parameters-functions-commands for more url parameters
var exportUrl = spreadsheet.getUrl().replace(/edit.*$/, urlString);
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
},
muteHttpExceptions: true
}
var response = UrlFetchApp.fetch(exportUrl, options);
if (response.getResponseCode() !== 200) {
Logger.log("Error exporting Sheet to PDF! Response Code: " + response.getResponseCode());
return;
}
var blob = response.getBlob();
var timestamp = new Date().toISOString();
// set name to spreadsheet_sheet_range_timestamp.pdf
blob.setName(spreadsheet.getName() + '_' + sheet.getSheetName() + '_' + exportRange + '_' + timestamp + '.pdf');
var folderId = 'enter your folder ID here';
// Create the PDF file in the specific folder
DriveApp.getFolderById(folderId).createFile(blob);
}
}
Note:
For more url parameters, see reference below.
This needs to be an installable trigger, not a simple one.
Output:
References:
Url parameters
Alan Well's answer

Auto Send Email When Checkbox is Checked - Google Sheet

I tried the script from Auto Email Function for Google Sheets Mobile and it worked the first time. When I tried to change the variables, it does not automatically send the email, unless I run the script again, it would then update the response sheet and then clears the checkbox. Please help me with this. Kindly see my code below.
function EmailNotification(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Course_AutoEmail'); //source sheet
var columnb = sheet.getRange('I:I'); //Column with check boxes
var columnbvalue = columnb.getValues();
var notifysheet = ss.getSheetByName('Responses'); //destination sheet
var data = [];
var rownum = [];
//Condition check in B:B (or check box column); If true copy the same row to data array
for (let i = 0; i < columnbvalue.length; i++) {
if (columnbvalue[i][0] === true) {
var columnb2 = sheet.getRange('I747:I'); //row started in row 747
columnb2.setValue('false');
data.push.apply(data, sheet.getRange(i + 1, 1, 1, 20).getValues());
//Copy matched ROW numbers to rownum
rownum.push(i);
//Copy data array to destination sheet
notifysheet.getRange(notifysheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data);
var activeRow = notifysheet.getLastRow();
var name = notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var employeeID = notifysheet.getRange(activeRow, 2).getDisplayValue();
var position = notifysheet.getRange(activeRow, 3).getDisplayValue();
var team = notifysheet.getRange(activeRow, 4).getDisplayValue();
var date = notifysheet.getRange(activeRow, 10).getDisplayValue();
var rec1 = notifysheet.getRange(activeRow, 19).getDisplayValue();
var rec2 = notifysheet.getRange(activeRow, 20).getDisplayValue();
var email = rec1 + "," + rec2;
var subject = name + ': 201 Completion';
//Body of the email message, using HTML and the variables from above
var message =
'<br><div style="margin-left:10px;">Hi, </div>' +
'<br><div style="margin-left:10px;">Good day!</div>' +
'<br><div style="margin-left:10px;"><b>' + name + '</b> has completed the course. </div>' +
'<br><div style="margin-left:20px;"><h3 style="text-decoration: underline; color: #f36f21">Employee Details: </h3></div>' +
'<div style="margin-left:25px;">Name: <b>' +
name +
'</b></div>' +
'<div style="margin-left:25px;">Position: <b>' +
position +
'</b></div>' +
'<div style="margin-left:25px;">Team: <b>' +
team +
'</b></div>' +
'<div style="margin-left:25px;">Completion Date: <b>' +
date +
'</b></div>' +
'<br><br><div style="margin-left:10px;">Let me know if you have any questions. </div>' +
'<br><div style="margin-left:10px;">Thanks! </div>';
MailApp.sendEmail(email, subject, '', {
htmlBody: message,
name: 'Updates',
});
}
}
}
I read your code.
if you don't want your checked checkbox unchecked in spreadsheet.
so you have to remove `columnb2.setValue('false');` line of code.
this line is made checkbox unchecked.
solution of other problems : http://one7techlab.com

how to remove two second copy of pdf

I use this code for generating a pdf file and save it in a folder of my invoice but it saves two copy one in the folder and one in google drive out of all folders, how to remove send copy of pdf in drive but not in folder.
the code is
function runBothfunctions(){
//function 1
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ss1 = ss.getSheetByName('sheet1')
var ss1Id = ss1.getSheetId()
var ss2 = ss.getSheetByName('sheet2')
var ssId = ss.getId()
var clientName = ss1.getRange(3,3).getValue()
var invoiceNumber = ss1.getRange(4,3).getValue()
var totalBill = ss1.getRange(29,9).getValue()
var d = new Date();
var fullDate = ('0' + d.getDate()).slice(-2) +"/"+ ('0' + (d.getMonth() +1)).slice(-2) +"/"+ (d.getYear().toString()).slice(-2)
var invoiceFileName = invoiceNumber + '_' + fullDate + '_' + clientName +'_'+ totalBill
var url = ss.getUrl()
url = url.replace(/edit$/,'')
var url_ext = 'export?exportFormat=pdf&format=pdf'
+ '&size=A4' // paper size: "legal" / "letter" / "A4"
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&gid=' + ss1Id // the sheet's Id
var token = ScriptApp.getOAuthToken()
// Convert sheet1 to PDF
var response = UrlFetchApp.fetch(url + url_ext, { headers: { 'Authorization': 'Bearer ' + token }})
var blob = response.getBlob().setName(invoiceFileName + '.pdf')
// Add the folder ID of the Drive folder where the PDF should be saved. Create a folder and copy this ID: www.goo.gl/TfgqrN
var invoiceURL = DriveApp.getFolderById('19_cTkcDHlekS- 7Y32BEzUVlhghC0UHMZ').createFile(blob).getUrl()
ss2.getRange(ss2.getLastRow() +1, 1).setFormula('=HYPERLINK("' + invoiceURL + '";"' + invoiceFileName + '")')
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
//create an array of the invoice numbers already created
var colArray = sheet.getRange(4, 3).getValues();
//sort the array values to find max
var maxInColumn = colArray.sort(function(a,b){return b-a})[0][

ImportXML fails - alternative?

I've created a spreadsheet to pull in data from two river gauges near my house to try and follow their relationship to the water level as it passes us, (it's an old mill) since more and more the country seems to be flooding!
Basically the sheet works perfectly but not when the spreadsheet isn't open/when I close the laptop. I thought openById and getSheetByName would solve this but I'm having no luck.
The ImportXML commands that I construct just return N/A when the sheet is not open. The script is on a timed trigger every 15mins. I have another basic script that rewrites the contents of the cells as values so that there is only one row of ImportXML commands at a time.This script is also on a timed trigger.
I've pasted the scripts below - apologies if they're not very eloquent, these are my first attempts!
function fetchData() {
var sheet = SpreadsheetApp.openById("0AgG7jQSg2ljFdGNpbFRjUTA1LXJwdmtPcmxkQnZpUHc").getSheetByName("River Levels");
var bredURL = "http://www.environment-agency.gov.uk/homeandleisure/floods/riverlevels/120743.aspx?stationId=4004";
var belURL = "http://www.environment-agency.gov.uk/homeandleisure/floods/riverlevels/120743.aspx?stationId=4002";
var ssBredLevel = "substring((//div[#class='plain_text']/p)[2],35,4)";
var ssBelLevel = "substring((//div[#class='plain_text']/p)[2],31,4)";
var ssTime = "substring(//div[#class='plain_text']/p[2],34,5)";
var ssDate = "substring(//div[#class='plain_text']/p[2],43,10)";
var commandBredLevel = "ImportXML(\"" + bredURL + "\",\"" + ssBredLevel + "\")"; // build ImportXML() command
var commandBredTime = "ImportXML(\"" + bredURL + "\",\"" + ssTime + "\")"; // build ImportXML() command
var commandBredDate = "ImportXML(\"" + bredURL + "\",\"" + ssDate + "\")"; // build ImportXML() command
var commandBelLevel = "ImportXML(\"" + belURL + "\",\"" + ssBelLevel + "\")"; // build ImportXML() command
var commandBelTime = "ImportXML(\"" + belURL + "\",\"" + ssTime + "\")"; // build ImportXML() command
var commandBelDate = "ImportXML(\"" + belURL + "\",\"" + ssDate + "\")"; // build ImportXML() command
sheet.appendRow(['Bredwardine',' ',' ',' ',' ','Belmont',' ',' ',' ',' ','=now()']); // append row
var lastrow = sheet.getLastRow(); // define last row
var bredLevel = sheet.getRange(lastrow, 2); // define ImportXML cell
var bredTime = sheet.getRange(lastrow, 3); // define ImportXML cell
var bredDate = sheet.getRange(lastrow, 4); // define ImportXML cell
var belLevel = sheet.getRange(lastrow, 7); // define ImportXML cell
var belTime = sheet.getRange(lastrow, 8); // define ImportXML cell
var belDate = sheet.getRange(lastrow, 9); // define ImportXML cell
bredLevel.setFormula(commandBredLevel);
bredTime.setFormula(commandBredTime);
bredDate.setFormula(commandBredDate);
belLevel.setFormula(commandBelLevel);
belTime.setFormula(commandBelTime);
belDate.setFormula(commandBelDate);
writeFormats();
}
function writeRows() {
var sheet = SpreadsheetApp.openById("0AgG7jQSg2ljFdGNpbFRjUTA1LXJwdmtPcmxkQnZpUHc").getSheetByName("River Levels");
var range = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn());
range.setValues(range.getValues());
};
function writeFormats() {
var sheet = SpreadsheetApp.openById("0AgG7jQSg2ljFdGNpbFRjUTA1LXJwdmtPcmxkQnZpUHc").getSheetByName("River Levels");
var lastcol = sheet.getLastColumn(); // define width of sheet
var lastrow = sheet.getLastRow(); // define last row
var penrow = lastrow-1; // define penultimate row
var formatting = sheet.getRange(penrow,1,1,lastcol); // fetch formatting from penultimate row
formatting.copyFormatToRange(sheet,1,lastcol,lastrow,lastrow); // paste formatting to last row
};