I have an issue with sheet. I try to convert a Sheet to PDF.
The script is working alamost fine, the only issue I have is that the sheet consist of three spreadsheet. I only want that the first spreadsheet is converted to PDF. Some any Idea
//If a sheet ID was provided, open that sheet, otherwise assume script is
//sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
//Get URL of spreadsheet, and remove the trailing 'edit'
var url = ss.getUrl().replace(/edit$/,'');
//Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
//Get array of all sheets in spreadsheet
var sheets = ss.getSheets();
//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=' + sheet.getSheetId() //the sheet's Id
//following parameters are optional...
+ '&size=A4' //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
+ '&gid=1672240374'
+ '&ir=false' //seems to be always false
+ '&ic=false' //same as ic
+ '&r1=1' //Start Row number - 1, so row 1 would be 0 , row 15 wold be 14
+ '&c1=0' //Start Column number - 1, so column 1 would be 0, column 8 would be 7
+ '&r2=78' //End Row number
+ '&c2=29'; //End Column number;
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
var response = UrlFetchApp.fetch(url + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + ' - ' + ss.getSheetByName("Timesheet").getRange("B5").getValue() + "_" + ss.getSheetByName("Timesheet").getRange("X5").getValue() + '.pdf');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
}```
It is working now
/**
* Export one or all sheets in a spreadsheet as PDF files on user's Google Drive,
* in same folder that contained original spreadsheet.
*
* Adapted from https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579#c25
*
* #param {String} optSSId (optional) ID of spreadsheet to export.
* If not provided, script assumes it is
* sheet-bound and opens the active spreadsheet.
* #param {String} optSheetId (optional) ID of single sheet to export.
* If not provided, all sheets will export.
*/
function savePDFs( optSSId, optSheetId ) {
//If a sheet ID was provided, open that sheet, otherwise assume script is
//sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
//Get URL of spreadsheet, and remove the trailing 'edit'
var url = ss.getUrl().replace(/edit$/,'');
//Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
//Get array of all sheets in spreadsheet
// var sheets = ss.getSheets();
//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=' + sheet.getSheetId() //the sheet's Id
//following parameters are optional...
+ '&size=A4' //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
+ '&gid=1672240374'
+ '&ir=false' //seems to be always false
+ '&ic=false' //same as ic
+ '&r1=1' //Start Row number - 1, so row 1 would be 0 , row 15 wold be 14
+ '&c1=0' //Start Column number - 1, so column 1 would be 0, column 8 would be 7
+ '&r2=78' //End Row number
+ '&c2=29'; //End Column number;
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
var response = UrlFetchApp.fetch(url + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + '_' + ss.getSheetByName("Timesheet").getRange("B5").getValue() + "_" + ss.getSheetByName("Timesheet").getRange("X5").getValue() + "_" + ss.getSheetByName("ECA-Points & Personal Nr.").getRange("K23").getValue() + "." + ss.getSheetByName("ECA-Points & Personal Nr.").getRange("K21").getValue() + '.pdf');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
Related
I have a Google Sheet Script that sends the page to an email as a PDF which has been working perfectly until yesterday. Suddenly it started sending corrupted PDF's that can not be opened.
The Script runs just fine, if just can not open up the PDF file as it says "Can Not Display - Invalid format".
Any ideas on why it may have stopped working?
function sendSheetToPdfwithA1MailAdress(){ // this is the function to call
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheets()[0]; // it will send sheet 0 which is the first sheet in the spreadsheet.
// if you change the number, change it also in the parameters below
var shName = sh.getName()
// This function uses a cell in the spreadsheet that names the file that is being saved as getfilename(). using this function will pull from a certain Cell (G4 in this case)
function getFilename() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('N1944E'); // Edit the sheet name as necessary
var cell = sheet.getRange('C8'); //Cell to pull file name from.
var filename = cell.getValue();
return filename;
}
sendSpreadsheetToPdf(0, shName, sh.getRange('C6').getValue(),"Air Attack Daily Fire Sheet " + getFilename() );
}
function sendSpreadsheetToPdf(sheetNumber, pdfName, email,subject, htmlbody) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = spreadsheet.getId()
var sheetId = sheetNumber ? spreadsheet.getSheets()[sheetNumber].getSheetId() : null;
var url_base = spreadsheet.getUrl().replace(/edit$/,'');
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
+ (sheetId ? ('&gid=' + sheetId) : ('&id=' + spreadsheetId))
// following parameters are optional...
+ '&size=A4' // paper size
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=true&printtitle=false&pagenumbers=true' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName(pdfName + '.pdf');
if (email) {
var mailOptions = {
attachments:blob, htmlBody:htmlbody
}
MailApp.sendEmail(
email,
subject+" (" + pdfName +")",
"html content only",
mailOptions);
MailApp.sendEmail(
Session.getActiveUser().getEmail(),
" "+subject+" (" + pdfName +")",
"html content only",
mailOptions);
}
}
I had the exact same issue, but I just figured it out. The problem is here:
var url_base = ss.getUrl().replace(/edit$/,'') + "export?";
getUrl() appears to be returning a different version of the url than it was before. It now appends the following on the url: "ouid=###########&urlBuilderDomain=YOURDOMAIN" check it out yourself by using the logger.
That is causing an issue with the pdf export. So I built my own url address by replacing that line with the following:
var url_base = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/" + "export?";
It now seems to be working! Here's the full code that generates my blob:
function generatePDF(pdfName, sheet, portrait){
var token = ScriptApp.getOAuthToken();
var params = {
headers: {
'Authorization': 'Bearer ' + token,
},
'muteHttpExceptions' : true
};
var sheetId = sheet.getSheetId();
var ss = sheet.getParent();
// var url_base = ss.getUrl().replace(/edit$/,'') + "export?";
var url_base = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/" + "export?";
var url_ext = 'exportFormat=pdf' //export as pdf
+ '&format=pdf' //export as pdf
+ '&gid=' + sheetId
+ '&size=letter' // paper size
+ '&portrait=' + portrait // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false' //optional headers and footers
+ '&printtitle=false' //optional headers and footers
+ '&pagenumbers=true' //page numbers
+ '&gridlines=true' // gridlines
+ '&fzr=true' // repeat row headers (frozen rows) on each page
var response = UrlFetchApp.fetch(url_base + url_ext, params);
var blob = response.getBlob().setName(pdfName + ".pdf");
return blob;
}
Try this:
function sendSpreadsheetToPdf(sheetNumber, pdfName, email,subject, htmlbody) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = spreadsheet.getId()
var sheetId = sheetNumber ? spreadsheet.getSheets()[sheetNumber].getSheetId() : null;
var url_base = "docs.google.com/spreadsheets/d" + spreadsheetId + "/export?";
var url_ext = 'exportFormat=pdf&format=pdf' //export as pdf
+ (sheetId ? ('&gid=' + sheetId) : ('&id=' + spreadsheetId))
// following parameters are optional...
+ '&size=A4' // paper size
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=true&printtitle=false&pagenumbers=true' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
},
'muteHttpExceptions' : true
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName(pdfName + '.pdf');
if (email) {
var mailOptions = {
attachments:blob, htmlBody:htmlbody
}
MailApp.sendEmail(
email,
subject+" (" + pdfName +")",
"html content only",
mailOptions);
MailApp.sendEmail(
Session.getActiveUser().getEmail(),
" "+subject+" (" + pdfName +")",
"html content only",
mailOptions);
}
}
Can you try this instead of your current blob declaration :
var blob = response.getBlob().getAs('application/pdf').setName(pdfName + ' .pdf');
References:
Class Blob
I am having a strange problem and am hoping someone can guide. We have been using the following script for a long time with no issue, converts sheet into PDF and stores it into the drive. Now for some reason the file being created is a text/html file in PDF format. I am not sure why this is happening now nothing else has changed on our side.
function convertSpreadsheetToPdf(email, spreadsheetId, sheetName, pdfName)
{
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) :
SpreadsheetApp.getActiveSpreadsheet();
spreadsheetId = spreadsheetId ? spreadsheetId : spreadsheet.getId()
var sheetId = sheetName ? spreadsheet.getSheetByName(sheetName).getSheetId() : null;
var pdfName = pdfName ? pdfName : spreadsheet.getName();
var parents = DriveApp.getFileById(spreadsheetId).getParents();
var folder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
var url_base = spreadsheet.getUrl().replace(/edit$/,'');
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
+ (sheetId ? ('&gid=' + sheetId) : ('&id=' + spreadsheetId))
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=true' // 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
var options = {
headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName(pdfName + '.pdf');
folder.createFile(blob);
}
I just started writing script and I'm trying to convert a Google spreadsheet (multiple sheets) to a PDF file by changing cell value (example A1, i try but i didn't obtain nothing) or each 8 hr. The script below works, but it only creates a PDF when i run the script. I've trying to add a project's trigger: time-based each 8 hr but i received an email: Bad value (line 4, file "Code") so in the folder there were no new pdf files.
function savePDFs( optSSId, optSheetId ) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) :
SpreadsheetApp.getActiveSpreadsheet();
// Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
//additional parameters for exporting the sheet as a pdf
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if
optSheetId is provided
+ (optSheetId ? ('&gid=' + sheet.getSheetId()) : ('&id=' + ss.getId()))
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=true' // 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
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
var date = Utilities.formatDate8new Date(). "GMT+2" ""hh:mm dd/MM/yyyy")
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/" +
url_ext, options);
var blob = response.getBlob().setName(ss.getName() + date + '.pdf');
//from here you should be able to use and manipulate the blob to send and
email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
When i tried to run the script automatically changing the cell value i wrote another script reported below (don't work):
function onEdit(e) {
var langName = 'Sheet1'
var langCell = 'A1'
var curSheet = e.range.getSheet()
if (curSheet.getName() === langName) {
if (e.range.getA1Notation() === langCell) {
savePDFs()
}
}
I have this script that emails the content of a speadsheet to all the collaborators on a regular basis.
function myFunction() {
var document = SpreadsheetApp.openById("123documentid456");
var editors = document.getEditors();
for(var i = 0; i < editors.length; i++){
MailApp.sendEmail(editors[i].getEmail(), "Subject", "Some message", {
attachments : [document.getAs(MimeType.PDF)]
});
}
}
It creates a PDF and emails it. The thing is the content does not display nicely as the PDF's orientation is portrait. Is there any way to make it export to landscape?
From here, this code could help
*************************************************
function savePDFs() {
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=letter' + //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(sheet.getName() + '.pdf');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
DocsList.createFile(blob);
//OR DriveApp.createFile(blob);
}
*************************************************
Notice this bit: '&portrait=false' + //orientation, false for landscape, true for portrait
Need some help, am somewhat confused!
I have written a google apps script for a spreadsheet, accessed from a custom menu, that should create a pdf of the spreadsheet page, and save it in my google drive. The code executes OK and a pdf is created, but all I get is a pdf of a google sign in page (for sheets). I am the owner of the spreadsheet and the drive folder and working in my Google Apps for Education account. If I try the full url (theurl) in a browser, I get the pdf I am after, so that works OK, so must be something to do with the blob or authorisation, but I can't see why? I must be missing something obvious. I have tried some of the authorisation code blocks I have seen but these just freeze the script. Any help much appreaciated. Tim
See attached for pdf output Order
Here is my code:
function spreadsheetToPDF(){
var key = '14vZzkfMj9XSk4pgbQc78s1pBmsakHABJk7_MSX6j7xs'; //docid
var index = 0; //sheet gid / number
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ActiveSheet = ss.getSheetByName('Order Form');
var timestamp = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'-'HHmm");
var supp_name = ActiveSheet.getRange("C12").getValue(); //supplier
var plainonum = ActiveSheet.getRange("C5").getValue(); //order number
var onum = ('0000' + plainonum ).slice(-4); //sets leading zeros to order number
var description = ActiveSheet.getRange("C18").getValue(); //description
var name = 'Order-' + onum +'-' + supp_name + '-' + description + '-' + timestamp + '.pdf'; //makes pdf filename
SpreadsheetApp.flush(); //ensures everything on spreadsheet is "done"
//make the pdf from the sheet
var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/'
+ key
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false&pagenumbers=false'
+ '&gridlines=false'
+ '&fzr=false' // do not repeat frozen rows on each page
+ '&gid='
+ index; //the sheet's Id
var docurl = UrlFetchApp.fetch(theurl);
var pdf = docurl.getBlob().setName(name).getAs('application/pdf');
//save the pdf to the folder on drive
try {
folder = DocsList.getFolder('Orders');
}
catch (e) {
folder = DocsList.createFolder('Orders');
}
folder.createFile(pdf);
}
Instead of using UrlFetchApp.fetch(), you can get a reference to the file using the DriveApp class.
Google DriveApp Class
The problem with using this method, is that I don't know of a way to do something like fit the PDF to one page, other than formatting the Sheet before it's saved.
Also, the DocsList class is now deprecated.
Maybe try something like this:
function createPDF() {
var fileToUse = 'FileID';
//Logger.log('fileToUse: ' + fileToUse);
var templateFile = DriveApp.getFileById(fileToUse);
var theBlob = templateFile.getBlob().getAs('application/pdf');
var folderID = folderToSaveTo;
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
//newFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
};
Thanks both, and to Zig for pointing me in the right direction. After a bit of digging around I found a script on labnol.org - doing something quite different but showing the oAuth authorisation part.
I needed a new variable
var token = ScriptApp.getOAuthToken();
and then to add some more code to the docurl variable
var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' + token } });
This provided the required authorisation for when the spreadsheet is not public.
Working function:
function spreadsheetToPDF(){
var key = '14vZzkfMj9XSk4pgbQc78s1pBmsakHABJk7_MSX6j7xs'; //docid
var index = 0; //sheet gid / number
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ActiveSheet = ss.getSheetByName('Order Form');
var timestamp = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'-'HHmm");
var supp_name = ActiveSheet.getRange("C12").getValue(); //supplier
var plainonum = ActiveSheet.getRange("C5").getValue(); //order number
var onum = ('0000' + plainonum ).slice(-4); //sets leading zeros to order number
var description = ActiveSheet.getRange("C18").getValue(); //description
var name = 'Order-' + onum +'-' + supp_name + '-' + description + '-' + timestamp + '.pdf'; //makes pdf filename
SpreadsheetApp.flush(); //ensures everything on spreadsheet is "done"
//make the pdf from the sheet
var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/'
+ key
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false&pagenumbers=false'
+ '&gridlines=false'
+ '&fzr=false' // do not repeat frozen rows on each page
+ '&gid='
+ index; //the sheet's Id
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' + token } });
var pdf = docurl.getBlob().setName(name).getAs('application/pdf');
//save the file to folder on Drive
var fid = '0B1quMlsbdFZyfkZRaWFQZVZLdFNDcC1hZGVqM25NNDhZblhVZktjamJLTVBXRXk5aThtcXc';
var folder = DriveApp.getFolderById(fid);
folder.createFile(pdf);
}
Must go and do some reading up about this!
What you see is by design. You are attempting to bypass user validation. If you look at the docs you will find getAs. https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getAs(String)