Accessing GPS / location data using Cloudpebble and PebbleJs - gps

Trying to show my current GPS location on my pebble by writing a simple script (see code below).
It all works just fine, but I cannot access the GPS-values.
The code is built on pebbles own geolocation example.
My problem is that I can only get the GPS data within the function locationSuccess() .
How do I access the GPS data (i.e. the values of myLat and myLong) outside that function? I want to put the GPS data into this line:
text : 'GPS:\n',
I am using CloudPebble and Pebble.js
The code:
var UI = require('ui');
var Vector2 = require('vector2');
var locationOptions = {
enableHighAccuracy: true,
maximumAge: 10000,
timeout: 10000
};
// Get the location
function locationSuccess(pos) {
console.log('\n****** START ******\nhere I am:\nlat= ' + pos.coords.latitude + ' lon= ' + pos.coords.longitude + '\n'); // Just to se that it works fine
var myLat = pos.coords.latitude;
var myLong = pos.coords.longitude;
console.log('My location\n' + myLat + ' and ' + myLong + '\n****** THE END 02 ******\n'); // This does also work fine
}
function locationError(err) {
console.log('location error (' + err.code + '): ' + err.message);
}
// Make an asynchronous request
navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
// Create a text object
var infotext = new UI.Text(
{
position: new Vector2(0, 0),
size: new Vector2(144, 168),
text : 'GPS:\n',
font: 'Gothic 28',
color: 'white',
textAlign: 'center'
});
// Create and show the location (vars x and y are empty - why?)
var infowindow = new UI.Window();
infowindow.add(infotext);
infowindow.show();

Since I can't add a comment to your post I will edit my first answer. Sorry for the mistakes in my first answer, I was not too familiar with the geolocation function.
You are not receiving any response at the end 02 because the function locationSuccess() has not ran yet, so no values have been assigned to myLat and myLong.
The reason that you are not receiving a response at the end 03 is because the function navigator.geolocation.getCurrentPosition() works asynchronously. It hasn't finished running when your next console.log executes so the values of your variables still haven't been set.
What I would suggest is to wrap your code that uses the geolocation into your locationSuccess function, since this success function is the intended area for that type of code anyhow.
Changes I Made:
By moving your success code into the success function, you no longer have to initialize the latitude and longitude variables, so I removed those from the code below. I also modified your original GPS window text infotext to display: "Loading GPS Data...". That way infowindow loads immediately, and shows a loading screen while navigator.geolocation.getCurrentPosition runs in the background.
Once the current position is found it will run the success function. I added a line to the end of this function to update the text in the GPS window to display the latitude and longitude. I also added a similar line to the error function to let the user know if something went wrong. You shouldn't need to call infowindow.add(infotext); or infowindow.show(); again for the text to update on the screen. I also moved navigator.geolocation.getCurrentPosition below the creation of the info window/text, so that the success/error functions cannot try to update the text before the text UI was created.
Updated Code:
var UI = require('ui');
var Vector2 = require('vector2');
var locationOptions = {
enableHighAccuracy: true,
maximumAge: 10000,
timeout: 10000
};
// Get the location
function locationSuccess(pos) {
console.log('\n****** START ******\nhere I am:\nlat= ' + pos.coords.latitude + ' lon= ' + pos.coords.longitude + '\n'); // Just to se that it works fine
var myLat = pos.coords.latitude;
var myLong = pos.coords.longitude;
console.log('My location\n' + myLat + ' and ' + myLong + '\n****** THE END 01 ******\n'); // This does work fine
//modify the text within infotext to show GPS data
infotext.text('GPS:\n' + myLat + '\n' + myLong);
}
function locationError(err) {
console.log('location error (' + err.code + '): ' + err.message);
//modify the text within infotext to alert user of error
infotext.text('Error Loading GPS Data!');
}
console.log('My location\n' + myLat + ' and ' + myLong + '\n****** THE END 02 ******\n');
// Create a text object
var infotext = new UI.Text(
{
position: new Vector2(0, 0),
size: new Vector2(144, 168),
text : 'Retrieving GPS Data...',
font: 'Gothic 28',
color: 'white',
textAlign: 'center'
});
// Create and show the location (vars x and y are empty - why?)
var infowindow = new UI.Window();
infowindow.add(infotext);
infowindow.show();
// Make an asynchronous request
navigator.geolocation.getCurrentPosition(locationSuccess, locationError,locationOptions);
console.log('My location\n' + myLat + ' and ' + myLong + '\n****** THE END 03 ******\n');
/edit
Original Answer:
The variables myLat and myLong are local variables in the function locationSuccess. To fix this issue you must change the scope in which myLat and myLong are defined.
In the below example, I defined the variables globally so that all scripts and functions can reference them.
var UI = require('ui');
var Vector2 = require('vector2');
//define variables globally
var myLat;
var myLong;
var locationOptions = {
enableHighAccuracy: true,
maximumAge: 10000,
timeout: 10000
};
// Get the location
function locationSuccess(pos) {
console.log('\n****** START ******\nhere I am:\nlat= ' + pos.coords.latitude + ' lon= ' + pos.coords.longitude + '\n'); // Just to se that it works fine
//assign value to globally scoped variables
myLat = pos.coords.latitude;
myLong = pos.coords.longitude;
console.log('My location\n' + myLat + ' and ' + myLong + '\n****** THE END 02 ******\n'); // This does also work fine
}
function locationError(err) {
console.log('location error (' + err.code + '): ' + err.message);
}
// Make an asynchronous request
navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
// Create a text object
var infotext = new UI.Text(
{
position: new Vector2(0, 0),
size: new Vector2(144, 168),
text : 'GPS:\n',
font: 'Gothic 28',
color: 'white',
textAlign: 'center'
});
// Create and show the location (vars x and y are empty - why?)
var infowindow = new UI.Window();
infowindow.add(infotext);
infowindow.show();
For further information on variable scope, this is a good reference.

Related

Reducing likelihood of PDF export error in Google Apps Script with Sheets [duplicate]

While downloading the pdf blob in google drive with UrlFetchApp.fetch method is causing two type of errors:
</div></div>This file might be unavailable right now due to heavy traffic. Try again.</div> [Written in downloaded PDF]
Exception: Timeout
Code Snippet:
function downloadasPDF(optSSId, optSheetId)
{
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
var preURL=ss.getUrl() //ss is an spreadsheet reference
var url = preURL.replace(/edit.*/,'');
var folder = DriveApp.getFolderById(FolderID);
// Get array of all sheets in spreadsheet
var sheets = ss.getSheets();
for (var i=0; i<sheets.length; i++) {
//Sheet length is 100+
Utilities.sleep("5000")
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
+ '&gridlines=false' // hide gridlines
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
}
var response = UrlFetchApp.fetch(url + url_ext, options);
var blob = response.getBlob().setName(spreadsheet.getName() + ' - ' + sheet.getName() + '.pdf');
folder.createFile(blob);
}
To counter above problem I am using:
Utilities.sleep(5000)
But still some files are causing error 1 mentioned above.
Question: Do we have any other better approach to handle two mentioned cases apart from sleep ?
Note: I am using G Suite Enterprise, Number of sheets to download are between 100-150 approx, 240 cells filled for each sheet & rest cells are empty.
Use a exponential back off function to sleep exponentially on failure. Failure can be checked with .getResponseCode():
var response = (function exponentialBackoff(i) {
Utilities.sleep(Math.pow(2, i) * 1000);
let data = UrlFetchApp.fetch(url + url_ext, options);
if (data.getResponseCode() !== 200) return exponentialBackoff(++i);
else return data;
})(1);

using google app script to make spreadsheet into a pdf but getting html

I created a new spreadsheet with a single sheet holding the subset of data of interest. My script is in the original spreadsheet. In that code I am attempting to create a PDF of the new spreadsheet. The URL that my code generates is:
exportUrl=https://docs.google.com/spreadsheets/d/1M82johI78eIrEf8u9RV_5kPgCDAaSfOcoGVYAyno5gE/?usp=drivesdk/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=false&gridlines=true&fzr=FALSE
The PDF generated in MyDrive does not have the icon of a PDF. If I preview it I see:
<!DOCTYPE html><html lang="en"><head><script nonce="siOEWKm8X/lqnbWRNS06ow">var DOCS_timing={}; DOCS_timing['pls']=new Date().getTime();</script><meta property="og:title" content="tempSs"><meta property="og:type" content="article"><meta property="og:site_name" content="Google Docs"><meta property="og:url" content="https://docs.google.com/spreadsheets/d/1M82johI78eIrEf8u9RV_5kPgCDAaSfOcoGVYAyno5gE/edit?usp=drivesdk/export?exportFormat%3Dpdf&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=false&gridlines=true&fzr=FALSE&usp=embed_facebook"><meta property="og:description" content="Sheet1
Abdalla,WilliamAbdalla
Aden,VickieAden
Allen,VeronicaAllen
etc.
When I download it and it has a file extension of html. If I open it the data is there but there is a lot of header stuff which makes no sense. If I change the file extension to pdf I get Error: Failed to load pdf
My code:
/**
* based on https://xfanatical.com/blog/print-google-sheet-as-pdf-using-apps-script/
*/
function exportAsPDF() {
fileName = “tempSs”;
var ssId = getMostRecentFile(fileName);
var ssBaseUrl = getMostRecentFile(fileName);
var blob = _getAsBlob(ssBaseUrl);
_exportBlob(blob, fileName);
}
/**
* Assume multiple spreadsheets with same name
* only want to use the most recent
*/
function getMostRecentFile(fileName) {
ssIt = DriveApp.getFilesByName(fileName);
var createDate, prevCreateDate, tempSsId;
var result = [];
while (ssIt.hasNext()) {
var file = ssIt.next();
result.push([file.getDateCreated(),file.getId(), file.getUrl()]);
}
var dTime = result.sort()[0][0];
var tempSsId = result.sort()[0][1];
var ssBaseUrl = result.sort()[0][2];
// Logger.log(“tempSsId: ” + tempSsId + ” dTime: ” + dTime);
return ssBaseUrl;
}
function _getAsBlob(ssUrlBase) {
// Logger.log(“ssUrlBase before remove edit: ” + ssUrlBase );
var ssUrlBase = ssUrlBase.replace(/edit?/,”);
Logger.log(“ssUrlBase: ” + ssUrlBase );
var exportUrl = ssUrlBase
+ ‘/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=false’
+ ‘&gridlines=true’
+ ‘&fzr=FALSE’;
Logger.log(‘exportUrl=’ + exportUrl);
var response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: ‘Bearer ‘ + ScriptApp.getOAuthToken(),
},
})
return response.getBlob();
}
Why am I not getting a valid PDF in MyDrive or when downloaded? My thanks to everyone. I would not have got this far without constant use of the fine answers on stackoverflow.
Modification points:
When I saw the URL of exportUrl=https://docs.google.com/spreadsheets/d/1M82johI78eIrEf8u9RV_5kPgCDAaSfOcoGVYAyno5gE/?usp=drivesdk/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=false&gridlines=true&fzr=FALSE. I notice that the modification point.
I think that /?usp=drivesdk/export? is the modification point. Please modify to /export?. I think that this is the reason of your issue.
And, in your script, the fonts of the double quotations and the single quotations are required to be modified. In your script, please modify “ and ” to ", and ‘ and ’ to '.
When above points are reflected to your script, it becomes as follows.
Modified script:
function exportAsPDF() {
fileName = "tempSs";
// var ssId = getMostRecentFile(fileName); // It seems that this variable is not used in your script.
var ssBaseUrl = getMostRecentFile(fileName);
var blob = _getAsBlob(ssBaseUrl);
_exportBlob(blob, fileName);
}
function getMostRecentFile(fileName) {
ssIt = DriveApp.getFilesByName(fileName);
var createDate, prevCreateDate, tempSsId;
var result = [];
while (ssIt.hasNext()) {
var file = ssIt.next();
result.push([file.getDateCreated(),file.getId(), file.getUrl()]);
}
var dTime = result.sort()[0][0];
var tempSsId = result.sort()[0][1];
var ssBaseUrl = result.sort()[0][2];
return ssBaseUrl;
}
function _getAsBlob(ssUrlBase) {
var ssUrlBase = ssUrlBase.replace(/\/edit.+/,""); // Modified
var exportUrl = ssUrlBase
+ '/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=false'
+ '&gridlines=true'
+ '&fzr=FALSE';
var response = UrlFetchApp.fetch(exportUrl, {headers: {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()}});
return response.getBlob();
}
Note:
From your question, I couldn't understand about _exportBlob(blob, fileName);. So it supposes that _exportBlob(blob, fileName); works.

Google Sheet Script (Email to PDF) suddenly sending corrupt PDFs

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

How to save or open a pdf file in pdf Viewer from response titanium

I want to open pdf file on click.
I tried below code but it didn't help me. It is giving error could not read file
var xhr = Ti.Network.createHTTPClient({
onload : function(e) {
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'file.pdf');
Ti.API.info('file == ' + f);
Ti.API.info('response = ' + this.responseData);
Ti.API.info('response = ' + JSON.stringify(this.responseData));
f.write(this.responseData);
Ti.API.info('write file == ' + f.write(this.responseData));
Ti.API.info('filepath == ' + f.nativePath);
Ti.API.info('get filepath == ' + f.getNativePath());
Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
action : Ti.Android.ACTION_VIEW,
type : 'application/pdf',
data : f.nativePath
}));
},
onerror : function(e) {
Alloy.Globals.loading.hide();
alert("Cannot retrieve PDF form web site");
},
timeout : 5000
});
xhr.open('GET', "https://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf");
xhr.send();
But I am getting Error as The document path is not valid.
I tried different way also using webview still not getting pdf on my app.
var win = Ti.UI.createWindow({
backgroundColor : '#fff'
});
var pdfViewer = Ti.UI.createWebView({
url : "http://lkn.ccomsys.com/assets/media/datafiles/gov/vvvv_Shehnai_Order1.pdf",
width : Titanium.UI.SIZE,
height : Titanium.UI.SIZE
});
Ti.API.info('pdfviewer == ' + JSON.stringify(pdfViewer));
win.add(pdfViewer);
win.open();
Thanks in advance.
I sorted this out
Step 1 : Created directory and file.
Step 2 : Write response to created file.
Step 3 : Open pdf with android intent.
Below is the complete code
var xhr = Ti.Network.createHTTPClient({
onload : function(e) {
Alloy.Globals.loading.hide();
var Settings = Titanium.Filesystem.getFile(Titanium.Filesystem.tempDirectory, 'Settings');
Ti.API.info("Created Settings: " + Settings.createDirectory());
Ti.API.info('Settings ' + Settings);
var newFile = Titanium.Filesystem.getFile(Settings.nativePath, 'Setting.pdf');
Ti.API.info('new file == ' + newFile);
if (newFile.exists() === false) {
// you don't need to do this, but you could...
newFile.write(this.responseData);
}
Ti.API.info('response = ' + this.responseData);
Ti.API.info('response = ' + JSON.stringify(this.responseData));
if (newFile.exists()) {
newFile.write(this.responseData);
Ti.API.info('newfile: ' + newFile.read());
}
Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
action : Ti.Android.ACTION_VIEW,
type : 'application/pdf',
data : newFile.nativePath
}));
},
onerror : function(e) {
Alloy.Globals.loading.hide();
alert("Cannot retrieve PDF form web site");
},
timeout : 5000
});
xhr.open('GET', "https://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf");
xhr.send();

Google Apps Script - Create PDf from Spreadsheet produces pdf of Google sign in page

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)