print spreadsheet as pdf with no margins - google-apps-script

I am trying to make things easier for my team so I want to have them print out a given area from my Google Sheets document into a pdf with predefined margins/printing settings. The printed area is not on the active spreadsheet.
I just moved over from Excel to Spreadsheets. I know some VBA but do not really know that much about GAS. I did quite a lot of research but all the samples I found are based on UiApp which not supported any longer.
I found some threads (where I think messages are missing?):
https://plus.google.com/u/1/115432608459317672860/posts/DQTbozyTsKk?cfem=1&pageId=none
Google Apps Script print sheet with margins
The last one I found was this one (PDF margins - Google Script) where I added the settings for margins (does it work that way though? I could not try it out yet because I do not know how to download the pdf. I tried do research but couldn't find anything..
var report = SpreadsheetApp.getActive();
var pdfName = "Angebot";
var sheetName = "Angebot";
var sourceSheet = report.getSheetByName(sheetName);
SpreadsheetApp.getActiveSpreadsheet().toast('Creating the PDF');
// export url
var url = 'https://docs.google.com/spreadsheets/d/'+report.getId()+'/export?exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=A4' // paper size legal / letter / A4
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='+sourceSheet.getSheetId(); // the sheet's Id
+ '&top_margin=0'
+ '&left_margin=0'
+ '&right_margin=0'
+ '&bottom_margin=0'
var token = ScriptApp.getOAuthToken();
// request export url
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var theBlob = response.getBlob().setName(pdfName+'.pdf');
//var attach = {fileName:'Monthly Report.pdf',content:pdf, mimeType:'application/pdf'};
var name = report.getRange("H1:H1").getValues(); // Get Name
var emailTo = report.getRange("H2:H2").getValues(); // Get email
var period = report.getRange("H3:H3").getValues(); // Get Reporting Period
var subject = " - TEST Monthly Report - " + period; // Construct the Subject Line
var message = "Hi " + name + ", here is your latest report for " + period; // email body text
// download pdf
}

Related

Fixing TypeError "range.getAs is not a function" with Apps Script's blob [duplicate]

This is my first time posting a question and I'm a complete novice so I apologize upfront if I don't include all the information you may need.
I have a Google Sheet that contains several tabs of data that is hand-keyed into a table. For eg:
Data Entry Table in Sheet
Within each sheet, there are numerous tables where the data from each "company" is entered that falls within a specific region.
What I'm trying to do is adjust a script that will go to the sheet specified, grab a range of cells for a specific table, convert it to a PDF and email it using the email address listed in another tab of the same sheet. I have searched online and found the following script:
function emailSpreadsheetAsPDF() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();
// This is the link to my spreadsheet with the Form responses and the Invoice Template sheets
// Add the link to your spreadsheet here
// or you can just replace the text in the link between "d/" and "/edit"
// In my case is the text: 17I8-QDce0Nug7amrZeYTB3IYbGCGxvUj-XMt8uUUyvI
const ss = SpreadsheetApp.openByUrl("SHEETURLGOESHERE/edit");
// We are going to get the email address from the cell "B7" from the "Invoice" sheet
// Change the reference of the cell or the name of the sheet if it is different
const value = ss.getSheetByName("emails").getRange("A2").getValue();
const email = value.toString();
// Subject of the email message
const subject = ss.getSheetByName("emails").getRange("B2").getValue();
// Email Text. You can add HTML code here - see ctrlq.org/html-mail
const body = "Sent via Generate Invoice from Google Form and print/email it";
// Again, the URL to your spreadsheet but now with "/export" at the end
// Change it to the link of your spreadsheet, but leave the "/export"
const url = 'SHEETURLGOESHERE/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&gid=879200050' // the sheet's Id. Change it to your sheet ID.
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20';
// You can find the sheet ID in the link bar.
// Select the sheet that you want to print and check the link,
// the gid number of the sheet is on the end of your link.
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
// Generate the PDF file
var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();
// Send the PDF file as an attachement
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments: [{
fileName: ss.getSheetByName("emails").getRange("B2").getValue() + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
// Save the PDF to Drive. The name of the PDF is going to be the name of the Company (cell B5)
const nameFile = ss.getSheetByName("01_Allegany_R3").getRange("A52").getValue().toString() +".pdf"
DriveApp.createFile(response.setName(nameFile));
}
While the above code does create the PDF and email it, it's not generating the PDF from the range I enter here:
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&gid=879200050' // the sheet's Id. Change it to your sheet ID.
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20';
If anyone is able to provide some help to me, I'd greatly appreciate it but I am a novice and not familiar with writing scripts so please be patient, if possible :)
Thank you
You need to put the gid parameter at the end of the export options:
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20'+
'&gid=879200050'; // the sheet's Id. Change it to your sheet ID.

urlfetchapp.fetch <url> are not permitted ERROR in Google Apps Script

I had a Google Apps Script code bound to a Google Spreadsheet that created a PDF file from one of its sheets using the urlfetchapp.fetch(url, options) function. Yesterday, without editing the code, it suddenly stopped working, showing the error "urlfetchapp.fetch are not permitted".
I checked other spreadsheet bound code I made for other Spreadsheet and it is not working anymore either, same error.
For context, I am using Google Workspace for my company, and dealing with sensitive data. But it was working just fine up until yesterday.
function CrearPDFysubirloalDrive(){
var Ss = SpreadsheetApp.getActiveSpreadsheet();
var Sheet= Ss.getSheetByName("Name")
var Longitud = Sheet.getLastRow();
var range = Sheet.getRange(1,1,Longitud,10);
var docId ="Planning";
var docId1Semana = Sheet.getRange('F5').getValue();
var docIdRevision = Sheet.getRange('C7').getValue();
var pdfname= docId+ " W"+docId1Semana+"-Rev "+docIdRevision;
//This is not important to the question
var tempst= Sheet.copyTo(Ss).setName(pdfname);
tempst.insertColumns(1);
tempst.setRowHeight(1,30)
tempst.setColumnWidth(1, 20);
tempst.setColumnWidth(12, 30);
tempst.deleteColumns(13,tempst.getMaxColumns()-12)
//tempst.deleteRows(Longitud+2, (tempst.getMaxRows()- (Longitud+2)))
tempst.getRange("A4:A5").setBackground("white");
var drawing = tempst.getDrawings();
for (let i=0; i<drawing.length;i++){
drawing[i].remove();
}
SpreadsheetApp.flush();
//THIS PART IS GIVING THE ERROR
var url = 'https://docs.google.com/spreadsheets/d/{ID}/export?'.replace('{ID}', Ss.getId());
var exportOptions = 'exportFormat=pdf&format=pdf' + // export as pdf / csv / xls / xlsx
'&size=letter' + // paper size legal / letter / A4
'&portrait=true' + // orientation, false for landscape
'&fitw=true&source=labnol' + // fit to page width, false for actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&top_margin=0.40' + //All four margins must be set!
'&bottom_margin=0.00' + //All four margins must be set!
'&left_margin=0.40' + //All four margins must be set!
'&right_margin=0.40' + //All four margins must be set!
'&gridlines=false' + //true/false
'&gid=' + tempst.getSheetId(); // the sheet's Id
var token = ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url + exportOptions, {
headers: {
Authorization: 'Bearer '+token
}
}).getBlob().setName(tempst.getName()+".pdf");
var pdfFile = DriveApp.createFile(blob);
var FolderDestino= DriveApp.getFolderById(<FOLDERID>);
FolderDestino.createFile(blob.setName(pdfname))
I am not an expert at coding by any means, but I suspect it is related to the Oauth token. Either that or the function has been deprecated.
EXACT ERROR CODE:
Exception: UrlFetch calls to https://docs.google.com/spreadsheets/d/*******/export?exportFormat=pdf&format=pdf&size=letter&portrait=true&fitw=true&source=labnol&sheetnames=false&printtitle=false&pagenumbers=false&gridlines=false&fzr=false&top_margin=0.40&bottom_margin=0.00&left_margin=0.40&right_margin=0.40&gridlines=false&gid=2141838874 are not permitted.
Any help?
Thank you in advance
It seems like there is a bug
The issue has already been filed on Google's Issue Tracker. I recommend you to "star" it to increase visibility.

Generate and Email PDF From a Range of Cells in Google Sheets

This is my first time posting a question and I'm a complete novice so I apologize upfront if I don't include all the information you may need.
I have a Google Sheet that contains several tabs of data that is hand-keyed into a table. For eg:
Data Entry Table in Sheet
Within each sheet, there are numerous tables where the data from each "company" is entered that falls within a specific region.
What I'm trying to do is adjust a script that will go to the sheet specified, grab a range of cells for a specific table, convert it to a PDF and email it using the email address listed in another tab of the same sheet. I have searched online and found the following script:
function emailSpreadsheetAsPDF() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();
// This is the link to my spreadsheet with the Form responses and the Invoice Template sheets
// Add the link to your spreadsheet here
// or you can just replace the text in the link between "d/" and "/edit"
// In my case is the text: 17I8-QDce0Nug7amrZeYTB3IYbGCGxvUj-XMt8uUUyvI
const ss = SpreadsheetApp.openByUrl("SHEETURLGOESHERE/edit");
// We are going to get the email address from the cell "B7" from the "Invoice" sheet
// Change the reference of the cell or the name of the sheet if it is different
const value = ss.getSheetByName("emails").getRange("A2").getValue();
const email = value.toString();
// Subject of the email message
const subject = ss.getSheetByName("emails").getRange("B2").getValue();
// Email Text. You can add HTML code here - see ctrlq.org/html-mail
const body = "Sent via Generate Invoice from Google Form and print/email it";
// Again, the URL to your spreadsheet but now with "/export" at the end
// Change it to the link of your spreadsheet, but leave the "/export"
const url = 'SHEETURLGOESHERE/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&gid=879200050' // the sheet's Id. Change it to your sheet ID.
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20';
// You can find the sheet ID in the link bar.
// Select the sheet that you want to print and check the link,
// the gid number of the sheet is on the end of your link.
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
// Generate the PDF file
var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();
// Send the PDF file as an attachement
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments: [{
fileName: ss.getSheetByName("emails").getRange("B2").getValue() + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
// Save the PDF to Drive. The name of the PDF is going to be the name of the Company (cell B5)
const nameFile = ss.getSheetByName("01_Allegany_R3").getRange("A52").getValue().toString() +".pdf"
DriveApp.createFile(response.setName(nameFile));
}
While the above code does create the PDF and email it, it's not generating the PDF from the range I enter here:
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&gid=879200050' // the sheet's Id. Change it to your sheet ID.
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20';
If anyone is able to provide some help to me, I'd greatly appreciate it but I am a novice and not familiar with writing scripts so please be patient, if possible :)
Thank you
You need to put the gid parameter at the end of the export options:
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&landscape=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&if=false' +
'&ic=false' +
'&r1=51' +
'&c1=0' +
'&r2=102' +
'&c2=20'+
'&gid=879200050'; // the sheet's Id. Change it to your sheet ID.

Everything works but the subject line blank... why? What am I missing?

I think this must be very easy to see, but I cannot see it! This script sends out a sheet as a PDF. It works well, except that the subject line is blank. I've tried substituting an actual string for the variable in the class gmailApp at the bottom, but the subject line is still blank when the email arrives. Help! Thank you.
P.S.-- note that I took out the email address for privacy.
function emailPDF(email, subject, body, sheetName) {
var email = "...";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Client');
var cost = sheet.getSheetValues(1,1,1,1).toLocaleString();
var subject = ss.getName();
var body = "Hi Serenity, the material cost is $" + cost +" Thank you!";
// Base URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers : {
'Authorization' : 'Bearer ' + token
}
}).getBlob().setName(ss.getName() + ".pdf");
// save PDF to drive
// var newFile = DriveApp.createFile(response).setName(sheet.getName() + ".pdf")
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody : body,
attachments : [response]
});
}
I've figured it out... this was just petty error. The spreadsheet has a lot of scripts. I picked up this script from a month ago, started from scratch and accidentally gave it the same function name. Both scripts were being called simultaneously, causing this result. Everything works now.
I appreciate your comment Lamblichus... I was so focused on the script being wrong that I didn't realize what was happening. Then I realized that it can't be wrong. You got me thinking the right way. Best.

How to get the “shareable link” of a Google Drive file via Google Apps Script and paste the link into a cell in Google Sheets?

I have a script that makes a PDF of my invoice and sends it to a Google drive folder.Now I want to get the "Shareable link" from the file it just made and paste it into a specific Cell in google Sheets. I don't have a coding background and at most I can understand and modify some code. So I'm using code I found online to create the PDF. I tried making my own code for the shareable link but I'm getting nowhere. Can anyone help me. This is the code I'm using for the PDF. If I can provide any more useful information please let me know. Thank you! :)
// Get the currently active spreadsheet URL (link)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var token = ScriptApp.getOAuthToken();
var sheet = ss.getSheetByName("Invoice");
//Creating an exportable URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
var folderID = "#### Folder ID ####"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var invoiceNumber = ss.getRange("'Invoice'!I16").getValue()
var InvoiceDate = ss.getRange("!I17").getValue()
var pdfName = "Invoice #"+ invoiceNumber + " - " + Utilities.formatDate(new Date(), "GMT-7", "MM-dd-yyyy");
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
// Convert individual worksheet to PDF
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob
var blobs = response.getBlob().setName(pdfName + '.pdf');
//saves the file to the specified folder of Google Drive
var newFile = folder.createFile(blobs);
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
}```
Intuitively, you can achieve a lot only by yourself, and this is the way to go at the beginning:
You want to retrieve the link of the pdf, so you know for sure that it can happen only when the pdf has been created, which is after this line var newFile = folder.createFile(blobs);
Therefore newFile is the PDF you've created, what's left is just to get the link of this file, you can use either getUrl() or getId():
var newFileLink = newFile.getUrl()
or
var newFileLink = "http://drive.google.com/uc?export=view&id=" + newFile.getId()
Now you have stored the link of the created PDF, and you want to write data into your spreadsheet within a specific cell, maybe you want it in J16, since you're using invoiceNumber = ss.getRange("'Invoice'!I16").getValue() to get a value from I16
Assuming you want to set a value in J16. Intuitively again, since getValue retrieve something, so maybe something link setValue will do the opposite:
var writePDFLink = ss.getRange("'Invoice'!J16").setValue(newFileLink)
Hope this was insightful.