I'm currently running a script that takes a sheet, converts it into PDF and emails it out to an email address nightly. I am doing this across three separate spreadsheets. Instead of it running separately on each spreadsheet, I wanted to see if there was a to call each spreadsheet, and run the script once and attach all the PDFs into one email. It works great by itself, but I feel like it would make sense if I can have one spreadsheet run the function once and incorporate the other spreadsheets as well. Any direction would be helpful Thank you!
The script I am using is as follows
function PDFtoEmail() {
var email = "email#gmail.com";
var ss = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(ss.getSheetByName('Schedule 1'));
var sheet = ss.getActiveSheet();
var subject = "Nightly Scheduled PDF";
var body = "";
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
var url_ext = 'exportFormat=pdf&format=pdf'
+ '&size=letter'
+ '&portrait=true'
+ '&fitw=true&source=labnol'
+ '&sheetnames=false&printtitle=false'
+ '&pagenumbers=false&gridlines=false'
+ '&fzr=true'
+ '&gid=';
var token = ScriptApp.getOAuthToken();
var sheets = ss.getSheets();
var PDFtoEmail = [];
for(var i = 0; i < 3; i++){
var response = UrlFetchApp.fetch(url + url_ext + sheets[i].getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
PDFtoEmail[i] = response.getBlob().setName("Schedule.pdf");
}
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
attachments:PDFtoEmail,
});
}
SpreadsheetApp.openByUrl() can open (for use by the script, they don't open in browser window) spreadsheets other than the one that is currently active. openByID is equally valid.
var sheets = [firstsheeturl, secondsheeturl,thirdsheeturl];
for(var i = 0; i < sheets.length; i++){
var ss = SpreadsheetApp.openByUrl(sheets[i]);
//code to do on all three sheets
}
Related
I am currently new to the google sheet script. I'm doing a simple report generator in google sheet using script. I already have a script that saves a generated pdf file to the google drive. In my google sheet there is a cell referenced to the main data source with dropdown data validation selecting the email of the person and will generate the other details (it a reference also based from that email in the same sheet). what I want is, when I run the script to save pdf file, it should automatically generate pdf file for each item in the dropdown validation list. Is this possible? Anyone who know this please.
this is my code that generate pdf file to the drive (i got this also from the net and made some changes)... thank you so much in advance.
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet2 = ss.getSheetByName('ID');
var gdid1 = sheet2.getRange('B1').getValue();
var gdid2 = sheet2.getRange('B4').getValue();
function onOpen() {
var ui = SpreadsheetApp.getUi()
ui.createMenu('ExportGDrive')
.addItem('Export BasicED', 'exportBasicED')
.addItem('Export College', 'exportCollege')
.addToUi()
}
function _exportBasic(blob, fileName, spreadsheet) {
blob = blob.setName(fileName)
var folder = DriveApp.getFolderById(gdid1)
var pdfFile = folder.createFile(blob)
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + fileName + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function _exportCollege(blob, fileName, spreadsheet) {
blob = blob.setName(fileName)
var folder = DriveApp.getFolderById(gdid2)
var pdfFile = folder.createFile(blob)
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + fileName + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function exportAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var blob = _getAsBlob(spreadsheet.getUrl())
_exportBlob(blob, spreadsheet.getName(), spreadsheet)
}
function _getAsBlob(url, sheet, range) {
var rangeParam = ''
var sheetParam = ''
if (range) {
rangeParam =
'&r1=' + (range.getRow() - 1)
+ '&r2=' + range.getLastRow()
+ '&c1=' + (range.getColumn() - 1)
+ '&c2=' + range.getLastColumn()
}
if (sheet) {
sheetParam = '&gid=' + sheet.getSheetId()
}
// A credit to https://gist.github.com/Spencer-Easton/78f9867a691e549c9c70
// these parameters are reverse-engineered (not officially documented by Google)
// they may break overtime.
var exportUrl = url.replace(/\/edit.*$/, '')
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=LETTER'
+ '&portrait=true'
+ '&fitw=true'
+ '&top_margin=0.75'
+ '&bottom_margin=0.75'
+ '&left_margin=0.7'
+ '&right_margin=0.7'
+ '&sheetnames=false&printtitle=false'
+ '&pagenum=UNDEFINED' // change it to CENTER to print page numbers
+ '&gridlines=FALSE'
+ '&fzr=FALSE'
+ sheetParam
+ rangeParam
Logger.log('exportUrl=' + exportUrl)
var response
var i = 0
for (; i < 5; i += 1) {
response = UrlFetchApp.fetch(exportUrl, {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
},
})
if (response.getResponseCode() === 429) {
// printing too fast, retrying
Utilities.sleep(3000)
} else {
break
}
}
if (i === 5) {
throw new Error('Printing failed. Too many sheets to print.')
}
return response.getBlob()
}
function exportCurrentSheetAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var currentSheet = SpreadsheetApp.getActiveSheet()
// Change the Cell for the name of the file (example: B3 for current sheet)
var blob = _getAsBlob(spreadsheet.getUrl(), currentSheet)
_exportBlob(blob, SpreadsheetApp.getActiveSheet().getRange('B3').getValue(), spreadsheet)
}
function exportBasicED() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var sheet1 = spreadsheet.getSheetByName('Generate-Basic Ed');
var name = sheet1.getRange('B3').getValue();
// Change the Cell for the name of the file (example: B3 for current sheet)
var blob = _getAsBlob(spreadsheet.getUrl(), sheet1)
_exportBasic(blob, name, spreadsheet)
}
function exportCollege() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var sheet1 = spreadsheet.getSheetByName('Generate-College');
var name = sheet1.getRange('B3').getValue();
// Change the Cell for the name of the file (example: B3 for current sheet)
var blob = _getAsBlob(spreadsheet.getUrl(), sheet1)
_exportCollege(blob, name, spreadsheet)
}
Try
function nextItem() {
var sh = SpreadsheetApp.getActive();
var data = sh.getRange('myValidationList').getValues();
for (var i = 0; i < data.length; i++) {
sh.getRange('A2').setValue(data[i][0]);
SpreadsheetApp.flush();
// here you can call the script to send pdf
Utilities.sleep(1000);
}
};
assuming that myValidationList is the list of valid data, avd A2 the cell in wich the validation applies.
I'm fairly new to the world of aumating sheets with scripts and ma still firmly in the 'cobble other peoples code together' phase of writing scripts.
I have a schedule in Google Sheets that display's different department overviews based on the contents of a cell ('B1'). I'm attempting to iterate a list of values through that cell and in each instance export the resulting sheet to pdf.
So far I've got it working, my next hurdle is getting it to export the pdf in landscape rather than portrait. I can see implementations using url export but I'm not confident enough (read keep breaking everything) to implement that in to the script below.
Any help greatly appreciated!
function PrintPDF(){
var df = DriveApp.getFolderById("folderID");
var arr = new Array();
var files = df.getFiles();
while( files.hasNext() ) {
var f = files.next();
arr.push( [ [ f.getId() ] , [ f.getLastUpdated() ] ] );
}
arr.sort( sortFunction );
function sortFunction( a , b ) {
var aDate = new Date(a[1]);
var bDate = new Date(b[1]);
if ( aDate === bDate ) return 0;
else if ( aDate < bDate ) return 1;
else return -1;
};
for( var i=0 ; i<arr.length ; i++ )
DriveApp.getFileById( arr[i][0] ).setTrashed( true );
//Create array of show codes
var Dss = SpreadsheetApp.getActive().getSheetByName('Value Lists')
var Tss = SpreadsheetApp.getActive().getSheetByName('PrintSheet')
var Shows = Dss.getRange('K3:K11').getValues()
var Count = Shows.length
var Code = Tss.getRange('B1')
Logger.log(Count)
Logger.log(Shows)
for (i=0;i<Count;i++){
Code.setValue(Shows[i])
HideBlankRows ()
const folderName = `foldername`;
var ss =SpreadsheetApp.getActiveSpreadsheet()
var name = "Department - "+ss.getRange('B1').getValue()
Logger.log(name)
DriveApp.getFoldersByName(folderName)
.next()
.createFile(ss
.getBlob()
.getAs(`application/pdf`)
.setName(name)
);
}
Code.setValue('')
}
function HideBlankRows() {
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets(); // array of all sheet objects in ss
var numSheets = ss.getNumSheets(); // count of sheets
for(sheet in sheets) {
if(sheets[sheet].getSheetName() == "AA") continue;
//show all the rows
sheets[sheet].showRows(1, sheets[sheet].getMaxRows());
//get data from column A
var data = sheets[sheet].getRange('A:A').getValues();
Logger.log(data)
//iterate over all rows
for(var i=0; i< data.length; i++){
//compare column, if no, then hide row
if(data[i][0] == 'Yes'){
sheets[sheet].hideRows(i+1);
}
}
}
}
Your code looks a bit cryptic to me. I don't understand why do you need the arr array if you nowhere use it. Etc.
But whatever. Suppose the code works fine and all you need is to save a PDF file with landscape orientation. In this case you need to replace these lines in your code:
DriveApp.getFoldersByName(folderName)
.next()
.createFile(ss
.getBlob()
.getAs(`application/pdf`)
.setName(name)
);
With this:
savePDFs(name);
And add at the end of your script the function savePDFs():
function savePDFs(name) {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var url = ss.getUrl();
//remove the trailing 'edit' from the url
url = url.replace(/edit$/, '');
//additional parameters for exporting the sheet as a pdf
var url_ext = 'export?exportFormat=pdf&format=pdf' + //export as pdf
//below parameters are optional...
'&size=a4' + //paper size
'&portrait=false' + //orientation, false for landscape, true for portrait
'&fitw=true' + //fit to width, false for actual size
'&sheetnames=false&printtitle=false&pagenumbers=false' + //hide optional headers and footers
'&gridlines=false' + //hide gridlines
'&fzr=false' + //do not repeat row headers (frozen rows) on each page
'&gid=' + sheet.getSheetId(); //the sheet's Id
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + url_ext, {
headers: { 'Authorization': 'Bearer ' + token }
});
var blob = response.getBlob().setName(name + '.pdf');
DriveApp.createFile(blob);
}
This function was taken from here: Change document orientation when exporting to PDF
I'm trying to make this script to work on google sheets app so it sends a pdf copy to my email when I type Send in cell L6
the code work perfect on computer but not on ipads , anyway to do this from app ?
function onEdit2(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var r = sheet.getRange('L6').getValue();
if (r == "Send") {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ssID = ss.getId();
var sheetgId = ss.getActiveSheet().getSheetId();
var sheetName = ss.getName();
var token = ScriptApp.getOAuthToken();
var email = "EMAIL HERE";
var subject = "Daily report ";
var body = "Please find the attached Daily report";
var url = "https://docs.google.com/spreadsheets/d/"+ssID+"/export?"
+ "format=xlsx" + "&gid="+sheetgId+ "&portrait=true" +
"&exportFormat=pdf";
var result = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {
attachments: [{
fileName: sheetName + ".pdf",
content: contents,
mimeType: "application//pdf"
}]
})
}
}
The way it worked for me by " installed Trigger "
from the script editor : Edit - current project Triggers
I added new trigger that will run the code below based on " On edit " and voila it worked , from sheets app if I typed " Send " in Cell L6 it will send a PDF copy of the active sheet to the email listed in the code.
function onEdit2(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var r = sheet.getRange('L6').getValue();
if (r == "Send") {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ssID = ss.getId();
var sheetgId = ss.getActiveSheet().getSheetId();
var sheetName = ss.getName();
var token = ScriptApp.getOAuthToken();
var email = "EMAIL HERE";
var subject = "Daily report ";
var body = "Please find the attached Daily report";
var url = "https://docs.google.com/spreadsheets/d/"+ssID+"/export?"
+ "format=xlsx" + "&gid="+sheetgId+ "&portrait=true" +
"&exportFormat=pdf";
var result = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {
attachments: [{
fileName: sheetName + ".pdf",
content: contents,
mimeType: "application//pdf"
}]
})
}
}
Create a Google Script in the very same Spreadsheet or in another one (Tools / Script editor), add the script you already have, grant the authorizations required, and trigger it with a simple form (Tools / Create a form) (trigger → Edit / Current project's triggers). The long URL to view the form can be easily opened by means of a URL shortener or something by the sort. Forms work in cell phones too and without need to sign in to your account. With this method you can even add a useless conditional password to run the script.
function createPDF(e) {
var input = e.values[1];
if (input == 'my_password'){
// your scripts to create and send the PDF goes here
}
}
It's a simplistic solution, but it works.
My script is looping through a list, at each index it is saving a sheet in my workbook as a PDF, then saving it to my google drive folder. There are 7 people in the list. The problem is that my script throws a 429 Error after the 6th PDF is exported. I am trying to figure out how to solve this error but I am quite new to google scripting so I need some help in the right direction.
Error Image
function ToPortrait() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var validation_sheet = ss.getSheetByName('ValidDSM');
var lastRow = validation_sheet.getLastRow();
var inputs = ss.getSheetByName('ValidDSM').getRange('A2:A'+lastRow).getValues();
var sheet2 = ss.getSheetByName('DSM');
var tab = ss.getSheetByName('DSMD');
var url = ss.getUrl().replace(/edit$/,'');
var sheets = ss.getSheets();
var optSheetId = 1123194386;
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
// Loop through List of 7
for (var i = 0; i < inputs.length; i++){
sheet2.getRange('B3').setValue(inputs[i][0]);
SpreadsheetApp.flush();
Utilities.sleep(500);
// Loop through all sheets, generating PDF files.
//for (var i=0; i<sheets.length; i++) {
//var sheet = sheets[i];
// If provided a optSheetId, only save it.
// if (optSheetId && optSheetId !== sheet.getSheetId()) continue;
//additional parameters for exporting the sheet as a pdf
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
+ '&gid=' + tab.getSheetId() //the sheet's Id
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=false' // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false&pagenumbers=false' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
// Get folder containing spreadsheet, for later export
var name = sheet2.getRange('B3').getValue();
var folderID = "1IsffOYYQOHZJKggUzRTntfjmJKN0F6ga"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var response = UrlFetchApp.fetch(url + url_ext, options)
var blob = response.getBlob().setName(name);
//save the pdf to drive
folder.createFile(blob);
}
}
I expect all 7 PDFs to be exported but only 6 are.
I have implemented a google script to isolate a specific sheet in a spreadsheet and then convert the sheet to a pdf and email the pdf. The code extracts the email address to send the email to from the sheet itself.
The total number of sheets in the spreadsheet are 9. The code works perfectly until sheet 6/7 (it is inconsistent in where the first fault occurs).
The first 5 or so emails work as intended with the correct sheet being emailed as a pdf that is fully functional.
Emails are sent to all the addresses, but the attached pdfs are unopenable and include the error "Whoops! There was a problem previewing this document" after sheet 6/7.
var d = new Date();
var month = new Array();
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
var n = d.getMonth() +1;
var Year = d.getYear();
if (n == 12) { n = 0; Year += +1;}
var m = month[n];
var subject = m + " " + Year;
var body = 'body text.'
var Clients_No = 9;
function sendEmailWithPdfAttach() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheets = source.getSheets();
var SpreadsheetName = source.getName();
SpreadsheetApp.flush();
for (var no_sent = 0; no_sent < Clients_No; no_sent++){
var sheetNum = no_sent;//no_sent;
var SheetName = sheets[sheetNum].getName();
var SheetID = sheets[sheetNum].getSheetId();
var Sheet = source.getSheetByName(SheetName);
var range = Sheet.getRange(1, 9); //change to 7, 2
var email = range.getValue();
var range_account_open = Sheet.getRange(14, 2);
var Account_open = range_account_open.getValue();
if (Account_open !== "Account Closed") {
var url = ss.getUrl();
url = url.replace(/edit$/,'');
url = url + 'export?exportFormat=pdf&format=pdf' +
'&size=A4' + //paper size
'&portrait=true' +
'&fitw=true' +
'&gridlines=false' +
'&fzr=false';
var request = {
"method": "GET",
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
},
"muteHttpExceptions": true
};
var url = Drive.Files.get(ssID)
.exportLinks['application/pdf'] + "&gid="+SheetID;
var blob = UrlFetchApp.fetch(url , request).getBlob();
blob.setName(sheets[sheetNum].getName() + ".pdf");
MailApp.sendEmail(email, subject, body, {attachments:blob});
//Utilities.sleep(1000);
}
}
};
What must I change so that all emails sent have pdfs that are openable and functional?
You may try the suggested actions in this link:
Clear your cookies and cache since beginning of time.
Try Incognito/private window.
Disable extensions/add-ons/plug-ins.
Disable all extensions by doing a browser reset.
Here's a link to the Google Support Center for how to do that: Chrome Browser Reset.
Try a different browser to see if it is a browser related issue
Make sure you are using the most current OS for your device. Here is a link to the operating systems Chrome supports.
Make sure you're using the latest version of Chrome.
Hope this helps!