How To Download / Export Sheets In Spreadheet Via Google Apps Script - google-apps-script

The task is to automate the manual process accomplished by the menu option "File | Download As | Plain Text"
I want to be able to control the saved file name, which cannot be done via the menu.
At the time this is invoked, the user would be sitting on the sheet in the spreadsheet. Ultimately, I'd make it a menu option, but for testing I'm just creating a function that I can run manually.
After reading several other threads for possible techniques, this is what I've come up with.
It builds a custom name for the file, makes the call, and the response code is 200.
Ideally, I'd like to avoid the open / save dialog. In other words, just save the file without additional user intervention. I'd want to save in a specific folder and I've tried it with a complete file spec, but the result is the same.
If I copy the URL displayed in the Logger and paste it into a browser, it initiates the open / save dialog, so that string works.
Here's the code as a function.
function testExportSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var oSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var sId = ss.getId();
var ssID=sId + "&gid=" + oSheet.getSheetId();
var url = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="
+ ssID + "&exportFormat=tsv";
Logger.log(url);
var fn = ss.getName() + "-" + oSheet.getSheetName() + ".csv";
var sHeaders = {"Content-Disposition" : "attachment; filename=\"" + fn + "\""};
var sOptions = {"contentType" : "text/html", "headers" : sHeaders};
Logger.log(sOptions);
x = UrlFetchApp.fetch(url, sOptions)
Logger.log(x.getResponseCode());
}

I have exported a spreadsheet as CSV directly into a local hard drive as follows:
Get the CSV content from current sheet using a variation of function convertRangeToCsvFile_() from the tutorial on this page https://developers.google.com/apps-script/articles/docslist_tutorial#section3
var csvFile = convertRangeToCsvFile_(...);
Then select a drive folder that is syncing to a local computer using Drive
var localFolder = DocsList.getFolderById("055G...GM");
And finally save the CSV file into the "local" folder
localFolder.createFile("sample.csv", csvFile);
That's it.

This app script returns a file for download instead of web page to display:
function doGet(){
var outputDocument = DocumentApp.create('My custom csv file name');
var content = getCsv();
var textContent = ContentService.createTextOutput(content);
textContent.setMimeType(ContentService.MimeType.CSV);
textContent.downloadAsFile("4NocniMaraton.csv");
return textContent;
}

In case you are looking to export all of the sheets in s spreadsheet to csv without having to manually do it one by one, here's another thread about it:
Using the google drive API to download a spreadsheet in csv format

The download can be done. But not the "Write to the hard drive" of the computer.
Write issue:
You mean write a file to the hard drive of the computer, using Google Apps Script? Sorry, but you will need more than GAS to do this. For security reasons, I doubt this is possible with only GAS, have never seen anything like this in GAS.
Google Drive API will let you do a download, just needs OAuth and the URL you gave.

This is the function that I found when looking up the same question. This function was linked to by #Mogsdad and the link no longer exists.
function convertRangeToCsvFile_(csvFileName) {
// Get the selected range in the spreadsheet
var ws = SpreadsheetApp.getActiveSpreadsheet().getActiveSelection();
try {
var data = ws.getValues();
var csvFile = undefined;
// Loop through the data in the range and build a string with the CSV data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// Join each row's columns
// Add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
I found it here and here

Related

How to extract files from .tar archive with Google Apps Script

Good day all,
I'm trying to get a tar.gz attachment from Gmail, extract the file and save it to Google Drive. It's a daily auto generated report which I'm getting, compressed due to >25mb raw size.
I got this so far:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Setup");
var gmailLabels = sheet.getRange("B2:B2").getValue(); //I have my Gmail Label stored here
var driveFolder = sheet.getRange("B5:B5").getValue(); //I have my GDrive folder name stored here
// apply label filter, search only last 24hrs mail
var filter = "has:attachment label:" + gmailLabels + " after:" + Utilities.formatDate(new Date(new Date().getTime()-1*(24*60*60*1000)), "GMT", "yyyy/MM/dd");
var threads = GmailApp.search(filter, 0, 1); // check only 1 email at a time
var folder = DriveApp.getFoldersByName(driveFolder);
if (folder.hasNext()) {
folder = folder.next();
} else {
folder = DriveApp.createFolder(driveFolder);
}
var message = threads[0].getMessages()[0];
var desc = message.getSubject() + " #" + message.getId();
var att = message.getAttachments();
for (var z=0; z<att.length; z++) {
var attName = att[z].getName()
var attExt = attName.search('csv')
if (attExt > 0){ var fileType = "csv"; }
else {
var attExt = attName.search('tar.gz');
if (attExt > 0){ var fileType = "gzip"; }
else {
threads[x].addLabel(skipLabel);
continue;
}
}
// save the file to GDrive
try {
file = folder.createFile(att[z]);
file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}
// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {
gz_file = folder.createFile(ungzippedFile);
gz_file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}
}
}
Everything works fine, but in the last step it only decompresses the .gz file saving .tar file in the Drive. What can I do with it next? The .tar file contains a .csv file which I need to extract and process afterwards.
I should probably add that I'm limited to use GAS only.
Any help warmly appreciated.
How about this answer? Unfortunately, in the current stage, there are no methods for extracting files from a tar file in Google Apps Script, yet. But fortunately, from wiki of tar, we can retrieve the structure of the tar data. I implemented this method with Google Apps Script using this structure data.
1. Unarchive of tar data:
Before you run this script, please set the file ID of tar file to run(). Then, run run().
Sample script:
function tarUnarchiver(blob) {
var mimeType = blob.getContentType();
if (!mimeType || !~mimeType.indexOf("application/x-tar")) {
throw new Error("Inputted blob is not mimeType of tar. mimeType of inputted blob is " + mimeType);
}
var baseChunkSize = 512;
var byte = blob.getBytes();
var res = [];
do {
var headers = [];
do {
var chunk = byte.splice(0, baseChunkSize);
var headerStruct = {
filePath: function(b) {
var r = [];
for (var i = b.length - 1; i >= 0; i--) {
if (b[i] != 0) {
r = b.slice(0, i + 1);
break;
}
}
return r;
}(chunk.slice(0, 100)),
fileSize: chunk.slice(124, 124 + 11),
fileType: Utilities.newBlob(chunk.slice(156, 156 + 1)).getDataAsString(),
};
Object.keys(headerStruct).forEach(function(e) {
var t = Utilities.newBlob(headerStruct[e]).getDataAsString();
if (e == "fileSize") t = parseInt(t, 8);
headerStruct[e] = t;
});
headers.push(headerStruct);
} while (headerStruct.fileType == "5");
var lastHeader = headers[headers.length - 1];
var filePath = lastHeader.filePath.split("/");
var blob = Utilities.newBlob(byte.splice(0, lastHeader.fileSize)).setName(filePath[filePath.length - 1]).setContentTypeFromExtension();
byte.splice(0, Math.ceil(lastHeader.fileSize / baseChunkSize) * baseChunkSize - lastHeader.fileSize);
res.push({fileInf: lastHeader, file: blob});
} while (byte[0] != 0);
return res;
}
// Following function is a sample script for using tarUnarchiver().
// Please modify this to your situation.
function run() {
// When you want to extract the files from .tar.gz file, please use the following script.
var id = "### file ID of .tar.gz file ###";
var gz = DriveApp.getFileById(id).getBlob().setContentTypeFromExtension();
var blob = Utilities.ungzip(gz).setContentTypeFromExtension();
// When you want to extract the files from .tar file, please use the following script.
var id = "### file ID of .tar file ###";
var blob = DriveApp.getFileById(id).getBlob().setContentType("application/x-tar");
// Extract files from a tar data.
var res = tarUnarchiver(blob);
// If you want to create the extracted files to Google Drive, please use the following script.
res.forEach(function(e) {
DriveApp.createFile(e.file);
});
// You can see the file information by below script.
Logger.log(res);
}
2. Modification of your script:
If this script is used for your script, for example, how about this? tarUnarchiver() of above script is used. But I'm not sure how you want to use this script. So please think of this as a sample.
Sample script:
// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {
var blob = ungzippedFile.setContentType("application/x-tar"); // Added
tarUnarchiver(blob).forEach(function(e) {folder.createFile(e.file)}); // Added
}
catch (e) {
Logger.log(e.toString());
}
}
In this modified script, the blob of ungzippedFile (tar data) is put to my script and run tarUnarchiver(). Then, each file is created to the folder.
Note:
When you run this script, if an error related to mimeType occurs, please set the mimeType of "tar" to the input blob.
As the method for setting the mimeType, you can use as follows.
blob.setContentTypeFromExtension() Ref
blob.setContentType("application/x-tar") Ref
It might have already been got the mimeType in the blob. At that time, setContentTypeFromExtension() and setContentType() are not required.
If you want to retrieve the file path of each file, please check the response from tarUnarchiver(). You can see it as a property of fileInf from the response.
Limitations:
When this script is used, there is the limitations as follows. These limitations are due to Google's specification.
About the file size, when the size of tar data is over 50 MB (52,428,800 bytes), an error related to size limitation occurs.
When the size of extracted file is over 50 MB, an error occurs.
When a single file size of extracted file is near to 50 MB, there is a case that an error occurs.
In my environment, I could confirm that the size of 49 MB can be extracted. But in the case of just 50 MB
, an error occurred.
Reference:
tar (wiki)
In my environment, I could confirm that the script worked. But if this script didn't work, I apologize. At that time, can you provide a sample tar file? I would like to check it and modify the script.

Google Apps Script ScriptApp.getUserTriggers returns empty array when called on another project that contains user triggers

I am trying to use the Google Apps Script ScriptApp getUserTriggers(spreadsheet) method to create a report that displays all of my user-installed triggers across all of my projects.
This code loops through all of the files in my Google Drive and makes an array of file IDs for all of the files that are Google Sheets files, and then attempts to get the triggers for each file:
var spreadsheetIds = [];
// get all spreadsheets in my google drive
var files = DriveApp.getFiles();
while (files.hasNext()) {
var file = files.next();
var type = file.getMimeType();
if (type == 'application/vnd.google-apps.spreadsheet') spreadsheetIds.push(file.getId());
}
var data = [];
try {
for (var i = 0; i < spreadsheetIds.length; i++) {
var ssOpen = SpreadsheetApp.openById(spreadsheetIds[i]);
Utilities.sleep(100);
var triggers = ScriptApp.getUserTriggers(ssOpen);
var spreadsheetName = ssOpen.getName();
Logger.log(spreadsheetName + ' triggers: ' + triggers.length);
for (var j = 0; j < triggers.length; j++) {
Logger.log(spreadsheetName + ' trigger ID: ' + triggers[j].getUniqueId());
data.push([spreadsheetName, triggers[j].getEventType(), triggers[j].getHandlerFunction(), triggers[j].getTriggerSource(), triggers[j].getTriggerSourceId(), triggers[j].getUniqueId()]);
}
}
} catch(e) {
Logger.log(e);
}
Many of my projects have user-installed triggers, but this just returns 0 for all of them (empty arrays are returned from ScriptApp.getUserTriggers()).
I am 100% sure that I am logged in to the same account when running this code as when I've set the triggers.
But just to be sure, when I add a test trigger to this project and run this code it correctly returns the number of triggers (which is 1):
function getCurrentProjectTriggersCount() {
Logger.log('Current project has ' + ScriptApp.getProjectTriggers().length + ' triggers.');
}
This has been previously reported as Issue 4562 - getProjectTriggers() always returns the triggers for the script it's contained in.
The usual advice is to visit and star the issue to increase its priority, and receive updates.

Export Google Sheet as TXT file (Fixed Width)

I am trying to replicate some functionality from a Excel document with some macros in a Google Spreadsheet. The end goal is to export a fixed-width txt file. Unfortunately, the vendor cannot use a CSV file. So, does anybody know of a way to generate a fixed-width TXT file using Google Scripts?
Just in case anybody else comes looking. I used a few sources and came up with this:
function saveAsFixedWidthTxt() {
// get Spreadsheet Name
var fileName = SpreadsheetApp.getActiveSpreadsheet().getName();
//var fileName = SpreadsheetApp.getActiveSheet().getSheetName();
// get Directory the Spreadsheet is stored in.
var dirName = DocsList.getFileById(SpreadsheetApp.getActive().getId()).getParents()[0].getName();
// Add the ".txt" extension to the file name
fileName = fileName + ".txt";
// Convert the range data to fixed width format
var txtFile = convertRangeToTxtFile_(fileName);
// Delete existing file
deleteDocByName(fileName);
// Create a file in the Docs List with the given name and the data
DocsList.getFolder(dirName).createFile(fileName, txtFile);
}
function convertRangeToTxtFile_(txtFileName) {
try {
var txtFile = undefined;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var rows = sheet.getDataRange();
var data = rows.getValues();
// Loop through the data in the range and build a string with the data
if (data.length > 1) {
var txt = "";
for (var row = 2; row < data.length; row++) {
for (var j=6; j<=10; j++){
if(data[row][j] != ''){
// Employee ID
var empID = "" + data[row][3];
txt += empID;
//Fill to 6 characters
for (i=empID.length; i<6; i++){
txt += " ";
}
// Name
var fullName = data[row][5] + " " + data[row][4]
txt += fullName;
//Fill to 43 characters
for (i=fullName.length; i<44; i++){
txt += " ";
}
// etc, etc to build out your line
txt += "\r\n";
}
}
}
txtFile = txt;
}
return txtFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
function deleteDocByName(fileName){
var docs=DocsList.find(fileName)
for(n=0;n<docs.length;++n){
if(docs[n].getName() == fileName){
var ID = docs[n].getId()
DocsList.getFileById(ID).setTrashed(true)
}
}
}
This will work:
export the sheet as a xlsx, then open that file in Excel.
Export that file as Space Delimited Text (.prn, for some reason).
Change the file extension on the resultant file to .txt.
This will result in a file like this:
Column Another Column 3
Val 1 2 $ 5.00
Or do you need to get a .txt file directly out of Google Apps Script?
Edit since a direct .txt download is necessary.
Here's how you could design a script to do that:
Find a way to convert sheet.getColumnWidth(n) to a number of spaces. You may find that there are 5 pixels to 1 character, or whatever the ratio
Run getColumnWidth() for each column to find the width you need for each column. Alternatively, find the length longest string in each cell.
Go through each cell and add it to a large string you begin building. As you add it, add the number of spaces necessary to match the value converted from getColumnWidth(). At the end of each row, append \n to represent a new line.
Once the output string is complete, you could then use the Content Service to download the text like so:
ContentService.createTextOutput(youBigString).downloadAsFile('filename.txt')
This would involve deploying your script as a web app, which could work well - you'd go to a URL and the page would trigger a download of the fixed-width file.
In my case, DocList use returns ReferenceError.#MSCF your lines 7 & 27 :
var dirName = DocsList.getFileById(SpreadsheetApp.getActive().getId()).getParents()[0].getName();
DocsList.getFolder(dirName).createFile(fileName, txtFile);
become
var dirName = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getParents().next().getId();
DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getParents().next().createFile(fileName, txtFile);

Export (or print) with a google script new version of google spreadsheets to pdf file, using pdf options

I'm trying to make a google script for exporting (or printing) a new version of google spreadsheet (or sheet) to pdf, with page parameters (portrait/landscape, ...)
I've researched about this and found a possible solution here.
There are several similar solutions like this, but only work with old version of google spreadsheet.
Please, consider this code:
function exportAsPDF() {
//This code runs from a NEW version of spreadsheet
var oauthConfig = UrlFetchApp.addOAuthService("google");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://spreadsheets.google.com/feeds/");
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous"); oauthConfig.setConsumerSecret("anonymous");
var requestData = { "method": "GET", "oAuthServiceName": "google","oAuthUseToken": "always" };
var ssID1="0AhKhywpH-YlQdDhXZFNCRFROZ3NqWkhBWHhYTVhtQnc"; //ID of an Old version of spreadsheet
var ssID2="10xZX9Yz95AUAPu92BkBTtO0fhVk9dz5LxUmJQsJ7yPM"; //ID of a NEW version of spreadsheet
var ss1 = SpreadsheetApp.openById(ssID1); //Old version ss object
var ss2 = SpreadsheetApp.openById(ssID2); //New version ss object
var sID1=ss1.getActiveSheet().getSheetId().toString(); // old version sheet id
var sID2=ss2.getActiveSheet().getSheetId().toString(); // new version sheet id
//For Old version, this runs ok.
var url1 = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="+ssID1+"&gid="+sID1+"&portrait=true"+"&exportFormat=pdf";
var result1 = UrlFetchApp.fetch(url1 , requestData);
var contents1=result1.getBlob();
var pdfFile1=DriveApp.createFile(contents1).setName("FILE1.pdf");
//////////////////////////////////////////////
var url2 = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="+ssID2+"&gid="+sID2+"&portrait=true"+"&exportFormat=pdf";
var result2 = UrlFetchApp.fetch(url2 , requestData);
var contents2=result2.getBlob();
var pdfFile2=DriveApp.createFile(contents2).setName("FILE2.pdf");
}
It works right and generates the file “FILE1.pdf”, that can be opened correctly. But for the new version of spreadsheet, it results in error 302 (truncated server response) at “var result2 = UrlFetchApp.fetch(url2 , requestData);”. Well, it’s ok because the url format for the new version doesn’t include the “key” argument. A correct url for new versions must be like "https://docs.google.com/spreadsheets/d/"+ssID2+"/export?gid="+sID2+"&portrait=true&format=pdf"
Using this for url2 (var url2 = "https://docs.google.com/spreadsheets/d/"+ssID2+"/export?gid="+sID2+"&portrait=true&format=pdf") it fails again with error “Authorization can’t be performed for service: google”.
Well, this error could be due to an incorrect scope for the RequestTokenUrl. I’ve found the alternative scope https://docs.google.com/feeds and set it: oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://docs.google.com/feed/");
After the code runs again, a new error happens at the line with UrlFetchApp.fetch(url2 , requestData);: “Error OAuth” … I don’t know how to continue … I’ve tested hundreds of variations without good results.
Any ideas? is correct the scope docs.google.com/feeds for new version of spreadsheets? is correct the oauthConfig?
Thanks in advance.
Here is my spreadsheet-to-pdf script. It works with the new Google Spreadsheet API.
// Convert spreadsheet to PDF file.
function spreadsheetToPDF(id,index,url,name)
{
SpreadsheetApp.flush();
//define usefull vars
var oauthConfig = UrlFetchApp.addOAuthService("google");
var scope = "https://docs.google.com/feeds/";
//make OAuth connection
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
//get request
var request = {
"method": "GET",
"oAuthServiceName": "google",
"oAuthUseToken": "always",
"muteHttpExceptions": true
};
//define the params URL to fetch
var params = '?gid='+index+'&fitw=true&exportFormat=pdf&format=pdf&size=A4&portrait=true&sheetnames=false&printtitle=false&gridlines=false';
//fetching file url
var blob = UrlFetchApp.fetch("https://docs.google.com/a/"+url+"/spreadsheets/d/"+id+"/export"+params, request);
blob = blob.getBlob().setName(name);
//return file
return blob;
}
I've had to use the "muteHttpExceptions" parameter to know exactly the new URL. With this parameter, I downloaded my file with the HTML extension to get a "Moved permanently" page with my final url ("https://docs.google.com/a/"+url+"/spreadsheets/d/"+id+"/export"+params").
And note that I am in an organization. So I've had to specify its domain name ("url" parameter, ie "mydomain.com").
(Copied from this answer.)
This function is an adaptation of a script provided by "ianshedd..." here.
It:
Generates PDFs of ALL sheets in a spreadsheet, and stores them in the same folder containing the spreadsheet. (It assumes there's just one folder doing that, although Drive does allow multiple containment.)
Names pdf files with Spreadsheet & Sheet names.
Uses the Drive service (DocsList is deprecated.)
Can use an optional Spreadsheet ID to operate on any sheet. By default, it expects to work on the "active spreadsheet" containing the script.
Needs only "normal" authorization to operate; no need to activate advanced services or fiddle with oAuthConfig.
With a bit of research and effort, you could hook up to an online PDF Merge API, to generate a single PDF file. Barring that, and until Google provides a way to export all sheets in one PDF, you're stuck with separate files.
Script:
/**
* 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=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 + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + ' - ' + 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
folder.createFile(blob);
}
}
Thank you!
Variant 2 works with me with options:
var requestData = {
"oAuthServiceName": "spreadsheets",
"oAuthUseToken": "always"
};
Then:
var ssID = ss.getId();
var sID = ss.getSheetByName(name).getSheetId();
//creating pdf
var pdf = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/" + ssID + "/export?gid=" + sID + "&portrait=false&size=A4&format=pdf", requestData).getBlob();
//folder to created pdf in
var folder = DriveApp.getFolderById(id);
//creating pdf in this folder with given name
folder.createFile(pdf).setName(name);
I can change image size, orientation etc. with listed parameters perfectly.

Can I generate a file from Google Sheets script?

I'm using Google Sheets to prototype a bunch of numerical data for something I'm doing.
Is there a way to export a subset to a text file?
Effectively, what I'm aiming to do is export a file I can include directly in the build for another project.
So is there a way to generate a text file for download?
If you have a Google Apps account, then you can use DocsList.createFile() to create the text file and save it in your documents list.
Section 3 of this tutorial shows how to save the selected range of a spreadsheet as a file in your documents list in CSV format. It could be modified pretty easily to save in a different format.
I have the texts of my project in some columns of a Google Spreadsheet.
I took this script tutorial from Google and modified it to select only a specific range (in the example below it's D4:D).
It generates a CSV file in your Drive root folder. It still doesn't download the file - I'm working on that now.
Hope it helps!
/* The code below is a modification from this tutorial: https://developers.google.com/apps-script/articles/docslist_tutorial#section3 */
/* The code below is a modification from this tutorial: https://developers.google.com/apps-script/articles/docslist_tutorial#section3 */
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "Save as CSV file", functionName: "saveAsCSV"}];
ss.addMenu("CSV", csvMenuEntries);
}
function saveAsCSV() {
// Name the file
fileName = "quests.csv";
// Convert the range data to CSV format
var csvFile = convertRangeToCsvFile_(fileName);
// Create a file in the root of my Drive with the given name and the CSV data
DriveApp.createFile(fileName, csvFile);
}
function convertRangeToCsvFile_(csvFileName) {
// Get from the spreadsheet the range to be exported
var rangeToExport = SpreadsheetApp.getActiveSpreadsheet().getRange("D4:D");
try {
var dataToExport = rangeToExport.getValues();
var csvFile = undefined;
// Loop through the data in the range and build a string with the CSV data
if (dataToExport.length > 1) {
var csv = "";
for (var row = 0; row < dataToExport.length; row++) {
for (var col = 0; col < dataToExport[row].length; col++) {
if (dataToExport[row][col].toString().indexOf(",") != -1) {
//dataToExport[row][col] = "\"" + dataToExport[row][col] + "\"";
dataToExport[row][col] = dataToExport[row][col];
}
}
// Join each row's columns
// Add a carriage return to end of each row, except for the last one
if (row < dataToExport.length-1) {
csv += dataToExport[row].join(",") + "\r\n";
}
else {
csv += dataToExport[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}