save a sheet from spreadsheet as pdf in same google drive folder - google-apps-script

I am trying to make a code that gets all files from a google drive folder, then converts all files to excel and save in same folder and also make pdf files from second sheet 'V2' of each spreadsheet and save in same folder.
I am successful in creating excel folder but pdf part is not working. I have copied code from many different sources.
function Generator(){
//Factors to change every month
var folderID = '14Bz9LLAiv2BgsT4bowxUtMfG2AsTxk91';
// Loop through all the files and save as excel and pdf.
var reportsFolder = DriveApp.getFolderById(folderID);
var files = reportsFolder.getFiles();
var TAB_NAME = 'V2' //For pdf
while(files.hasNext()) {
var file = files.next();
var bnkFile = SpreadsheetApp.getActiveSpreadsheet();
var name = file.getName();
//Creating Excel files
var url = "https://docs.google.com/spreadsheets/d/" + file.getId() + "/export?format=xlsx&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url).getBlob().setName(name + ".xlsx"); // Modified
reportsFolder.createFile(blob);
//Creating PDF files
var VName = name.replace("REPORT", "V2");
var V2Sheet = bnkFile.getSheetByName(TAB_NAME);
var url2 = "https://docs.google.com/spreadsheets/d/" + V2Sheet.getId() + "/export?exportFormat=pdf&format=pdf" + ScriptApp.getOAuthToken();
var blob2 = UrlFetchApp.fetch(url2).getBlob().setName(VName + ".pdf"); // Modified
reportsFolder.createFile(blob2);
}
}
Any simple solution for generating PDFs?

Explanation:
You need to specify both the id of the spreadsheet file but also the gid of the sheet itself.
Replace
var url2 = "https://docs.google.com/spreadsheets/d/" + V2Sheet.getId() + "/export?exportFormat=pdf&format=pdf" + ScriptApp.getOAuthToken();
with
var url2 = "https://docs.google.com/spreadsheets/d/"+ file.getId() + "/export?format=pdf&id="+file.getId()+"&gid="+V2Sheet.getSheetId();
Replace
var bnkFile = SpreadsheetApp.getActiveSpreadsheet();
with
var bnkFile = SpreadsheetApp.openById(file.getId());
to get the spreadsheet object of the file. Your current code gets the active spreadsheet which is the spreadsheet that this script is attached to.
Also use the requestData object as I define it in my solution.
Solution:
function Generator(){
//Factors to change every month
var folderID = '14Bz9LLAiv2BgsT4bowxUtMfG2AsTxk91';
// Loop through all the files and save as excel and pdf.
var reportsFolder = DriveApp.getFolderById(folderID);
var files = reportsFolder.getFiles();
var TAB_NAME = 'V2' //For pdf
while(files.hasNext()) {
var file = files.next();
if(file.getMimeType()=='application/vnd.google-apps.spreadsheet'){
var bnkFile = SpreadsheetApp.openById(file.getId());
var name = file.getName();
//Creating Excel files
var url = "https://docs.google.com/spreadsheets/d/" + file.getId() + "/export?format=xlsx&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url).getBlob().setName(name + ".xlsx"); // Modified
reportsFolder.createFile(blob);
//Creating PDF files
var VName = name.replace("REPORT", "V2");
var V2Sheet = bnkFile.getSheetByName(TAB_NAME);
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url2 = "https://docs.google.com/spreadsheets/d/"+ file.getId() + "/export?format=pdf&id="+file.getId()+"&gid="+V2Sheet.getSheetId();
var blob2 = UrlFetchApp.fetch(url2,requestData).getBlob().setName(VName + ".pdf"); // Modified
var pdfFile = reportsFolder.createFile(blob2);
var pdfUrl = pdfFile.getUrl(); // <- pdfUrl will give you the url of the pdf file.
}
}
}

Related

Google Sheet: Replace file with the same name

I'm currently generating a PDF file from an active sheet. Is there a way to overwrite or replace the file in the google drive without putting it to trash? I have this code that I saw online.
if (files.hasNext()) {
files.next().setTrashed(true);
}
Am I using the code right or there is another way for me to do it?
I used that code on the function below.
function _exportBlob(blob, fileName) {
var timeZone = Session.getScriptTimeZone();
var date = Utilities.formatDate(new Date(), timeZone, "yyyy");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var fileName = "FORM137 - " + ss.getRange("REPORT CARD!D12").getValue() + " - ARCS" + date;
var ssID = ss.getId();
var ssFile = DriveApp.getFileById(ssID);
blob = blob.setName(fileName)
var parentFolder = DriveApp.getFileById(ss.getId()).getParents().next();
var subFolder = parentFolder.getFoldersByName("CARDS").next();
var files = subFolder.getFilesByName(getFilename());
if (files.hasNext()) {
files.next().setTrashed(true);
}
var pdfFile = subFolder.createFile(blob);
if (pdfFile) {
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + fileName + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
}
Here's the getFilename function:
function getFilename() {
var ss = SpreadsheetApp.getActive();
var filename = "FORM137 - " + ss.getRange("REPORT CARD!D12").getValue() + " - ARCS" + date;
return filename;
}
I believe your goal as follows.
You want to overwrite blob to the existing file of getFilename().
In this case, I would like to propose to use the method of "Files: update" in Drive API.
Before you use this script, please enable Drive API at Advanced Google services.
From:
var files = subFolder.getFilesByName(getFilename());
if (files.hasNext()) {
files.next().setTrashed(true);
}
var pdfFile = subFolder.createFile(blob);
To:
var files = subFolder.getFilesByName(getFilename());
var pdfFile = files.hasNext() ? DriveApp.getFileById(Drive.Files.update({}, files.next().getId(), blob).id) : subFolder.createFile(blob);
In this modification, when the file of getFilename() is not existing, a new file is created.
Reference:
Files: update

Get specific Range to Export

can anyone help me with my problem?
Need to export a specific range (A1:J39), not the full sheet.
function SavePDFtoDrive() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ltrsht = ss.getSheetByName("Schichtübergabe-Protokoll");
var datasheet = ss.getSheetByName("Daten");
var sheets=SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i =0;i<sheets.length;i++){
if(sheets[i].getName()!="Schichtübergabe-Protokoll"){ sheets[i].hideSheet() }
}
var pdf = DriveApp.getFileById(ss.getId());
var theBlob = pdf.getBlob().getAs('application/pdf').setName(datasheet.getRange("I8").getValue()+".pdf");
var folderID = "1dyKFNvQWrSiNFA8N5PyUMPJQpWSVhsLf"; // Folder id to save in a folder
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
}
Answer:
Rather than getting your blob using DriveApp, you can obtain your blob from an export URL using UrlFetchApp.
More Information:
When you use DriveApp to create a blob of a file, it doesn't have the functionality to read the specifics of the file. In this case, you can't specify the range of a Sheet you wish to export with DriveApp.
You can, however, build a URL with all your export parameters and create your export in Drive by creating a blob of the response and creating it in Drive.
Code:
function SavePDFtoDrive() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ltrsht = ss.getSheetByName("Schichtübergabe-Protokoll");
var datasheet = ss.getSheetByName("Daten");
// build your URL:
var url = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?"
//define your parameters:
var params = 'exportFormat=pdf&format=pdf'
+ '&portrait=false'
+ '&fitw=true'
+ '&gid=' + ltrsht.getSheetId()
+ '&range=A1:J39';
//get token for UrlFetch:
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + params, {
'headers': {
'Authorization': 'Bearer ' + token
}
});
var fileName = datasheet.getRange("I8").getValue() + ".pdf";
var theBlob = response.getBlob().setName(fileName);
var folderID = "1Hp-P1dzWaKHhhS2FTPzKib6pwJibS12t";
var folder = DriveApp.getFolderById(folderID);
folder.createFile(theBlob);
}
References:
Class UrlFetchApp | Apps Script | Google Developers
Related Questions/Answers:
how to print a long Google sheets column in fewer columns

google app script : how to change folder destination

I am using the script below to export a google spreadsheet to CSV (thank you ziganotschka).
I am trying to save the CSV in another folder than the same as my Spreadsheet.
I have a folder containing my spreadsheet and inside a subfolder ("Final_Export) where I would like the CSV to save in.
The app script I use is :
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssname = ss.getName();
var sheet = ss.getActiveSheet();
var folder = DriveApp.getFileById(ss.getId()).getParents().next();
var fileName = ssname + ".csv";
var url = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?
exportFormat=csv&format=csv";
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
folder.createFile(response.getBlob().setName(fileName));
}
Thank you for your help
Finally, I found the solution.
I had this code :
var parentFolder = DriveApp.getFolderById("myFolderDestinationId");
var folder = parentFolder;

accessing spreadsheet by ID

I am using google Apps script.
I need to access some information in the spreadsheet.
I navigate to the file and find its ID.
However, the function
var fileID = file.getId()
var activityName = Sheets.Spreadsheets.Values.get (fileID,'B1:B4'); doesn't seem to accept the ID, even thought the ID is correct as I logged it and checked.
function getTheInformation() {
//navigate to the correct folder
var dApp = DriveApp;
var folderIter = dApp.getFoldersByName("scriptFolder");
var folder = folderIter.next();
//reality check
Logger.log(folder);
var filesIter = folder.getFiles();
var i = 1;
//cycle through the files
while (filesIter.hasNext())
{
var file = filesIter.next();
var fileID = file.getId()
var fileName = file.getName();
//here the code breaks
var activityName = Sheets.Spreadsheets.Values.get (fileID,'B1:B4');
i++;
Logger.log(fileName + " file ID " + fileID);
}
}
This worked for me:
function getTheInformation() {
var dApp = DriveApp;
var folderIter = dApp.getFoldersByName("Questions");
var folder = folderIter.next();
var filesIter = folder.getFiles();
while (filesIter.hasNext()) {
var file = filesIter.next();
var fileID = file.getId()
var fileName = file.getName();
if(fileName=='StackOverflow1') {
var values = Sheets.Spreadsheets.Values.get (fileID,'Sheet1!B1:B4')
Logger.log(values);
}
}
}
Things I did a little different: I added the sheet name to the range and I also checked for the correct file name.

How do you get the folder from where the file is from in Google Drive to display in Google Sheets

Currently the code I have displays just the file name, file url source, and file type, I tried using getFolder() but that does not seem to be working for me, this is what I have so far. Any ideas on how best to implement the folder functions (if needed or not) in order to display in a separate column where each file is from folder-wise?
function search(Phrase, FolderID) {
// Prompt the user for a search term
var searchTerm = Browser.inputBox("Enter the string to search for:");
// Get the active spreadsheet and the active sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// Set up the spreadsheet to display the results
var headers = [["File Name", "File Type", "URL"]];
sheet.clear();
sheet.getRange("A1:C1").setValues(headers);
// Search the files in the user's Google Drive for the search term based on if the word is included in thefile or name
// Search Reference Guide: https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
var files = DriveApp.searchFiles("fullText contains '"+searchTerm.replace("'","\'")+"'");
//var SearchString = 'fullText contains "' + Phrase + '" and "' + FolderID + '" in parents';
//var files = DriveApp.searchFiles(SearchString);
// create an array to store our data to be written to the sheet
var output = [];
// Loop through the results and get the file name, file type, and URL
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
var type = file.getMimeType();
var url = file.getUrl();
// push the file details to our output array (essentially pushing a row of data)
output.push([name, type, url]);
}
// write data to the sheet
sheet.getRange(2, 1, output.length, 3).setValues(output);
}
EDIT
function search(Phrase, FolderID) {
// Prompt the user for a search term
var searchTerm = Browser.inputBox("Enter the string to search for:");
// Get the active spreadsheet and the active sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// Set up the spreadsheet to display the results
var headers = [["File Name", "File Type", "URL", "Folder"]];
sheet.clear();
sheet.getRange("A1:D1").setValues(headers);
// Search the files in the user's Google Drive for the search term based on if the word is included in thefile or name
// Search Reference Guide: https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
var files = DriveApp.searchFiles("fullText contains '"+searchTerm.replace("'","\'")+"'");
//var SearchString = 'fullText contains "' + Phrase + '" and "' + FolderID + '" in parents';
//var files = DriveApp.searchFiles(SearchString);
// create an array to store our data to be written to the sheet
var output = [];
// Loop through the results and get the file name, file type, and URL
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
var type = file.getMimeType();
var url = file.getUrl();
var folderNames = "";
var folders = file.getParents();
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
folderNames += folder.getName() + ", ";
}
// push the file details to our output array (essentially pushing a row of data)
output.push([name, type, url, folders]);
}
// write data to the sheet
sheet.getRange(2, 1, output.length, 4).setValues(output);
}
You can access a file's folder with the method getParents().
In you code, it could look like:
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
var type = file.getMimeType();
var url = file.getUrl();
var folderNames = "";
var folders = file.getParents();
while (folders.hasNext()) {
var folder = folders.next();
folderNames += folder.getName() + ", ";
}
// push the file details to our output array (essentially pushing a row of data)
output.push([name, type, url, folderNames]);
}
The other methods of the class file can be found here