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
Related
When I run my function in Apps Script its working fine but when I add it in a trigger this error always occurs in first run.
TypeError: folder.getFiles is not a function
This is the code. I use this code to get all files in all folders and subfolders.
var level=0;
function getFnF(folder) {
var folder= folder || DriveApp.getFolderById('root folder ID');
var ss=SpreadsheetApp.openById('google sheet ID');
var sh=ss.getSheetByName('List');
var files=folder.getFiles();
while(files.hasNext()) {
var file=files.next();
var fileid = file.getId();
var TimeStamp = Utilities.formatDate(new Date(), "GMT+8", "MMMM dd, yyyy HH:mm:ss")
var filesize = file.getSize()/ 1024 / 1024;
var lastrow = sh.getLastRow();
var filename =file.getName();
sh.appendRow([TimeStamp,lastrow,filename,file.getName(),filesize.toFixed(2),fileid);
Logger.log('Item added in list: ['+ lastrow+"] " + filename);
}
var subfolders=folder.getFolders()
while(subfolders.hasNext()) {
var subfolder=subfolders.next();
//subfolders only
level++;
getFnF(subfolder);
}
level--;
}
I hope you can help me.
From When I run my function in apps script its working fine but when I add it in a trigger this error always occurs in first run., I'm not sure about the kind of trigger. But when the function is run by a trigger, the event object is given to the 1st argument. So, in this case, how about the following modification?
Modified script:
var level = 0;
function getFnF(e, folder = DriveApp.getFolderById('root folder ID')) {
var ss = SpreadsheetApp.openById('google sheet ID');
var sh = ss.getSheetByName('Sheet1');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
var fileid = file.getId();
var TimeStamp = Utilities.formatDate(new Date(), "GMT+8", "MMMM dd, yyyy HH:mm:ss")
var filesize = file.getSize() / 1024 / 1024;
var lastrow = sh.getLastRow();
var filename = file.getName();
sh.appendRow([TimeStamp, lastrow, filename, file.getName(), filesize.toFixed(2), fileid]);
Logger.log('Item added in list: [' + lastrow + "] " + filename);
}
var subfolders = folder.getFolders()
while (subfolders.hasNext()) {
var subfolder = subfolders.next();
//subfolders only
level++;
getFnF(e, subfolder);
}
level--;
}
By this modification, when the function getFnF by a trigger, the function is run as the initial value of folder of DriveApp.getFolderById('root folder ID').
By the way, when you want to run this function from another function instead of the trigger, please call this as getFnF("dummy", folder).
Hi Facing error while running code of Coverting excel to csv. Please guide what to edit to solve the query.
function makeCSV() {
var SourceFolder = DriveApp.getFolderById("1aoonhCebvI5DddvJVGTzBvWs2BPn_yXN")
var DestinationFolder = DriveApp.getFolderById("1LB0Em4vYFJV8vJIEiLt6Tg5pnzPATZEj")
var searchQuery = "mimeType='" + MimeType.MICROSOFT_EXCEL + "' or mimeType='" +
MimeType.MICROSOFT_EXCEL_LEGACY + "'";
var sourceFiles = SourceFolder.searchFiles(searchQuery);
var now = new Date();
var properties = PropertiesService.getScriptProperties();
var cutoff_datetime = properties.getProperty('last_execution_time');
if(cutoff_datetime)
cutoff_datetime = new Date(cutoff_datetime);
while (sourceFiles.hasNext()){
var sourceFile = sourceFiles.next();
if(!cutoff_datetime || sourceFile.getDateCreated() > cutoff_datetime){
var fileId = sourceFile.getId();
var Spreadsheet = Drive.Files.copy({mimeType: MimeType.csv, parents:
[{id:"1LB0Em4vYFJV8vJIEiLt6Tg5pnzPATZEj"}]}, fileId);
}
}
properties.setProperty('last_execution_time',now.toString());
}
Unfortunately, XLSX data cannot be directly converted to CSV data using Google Apps Script. And, Drive.Files.copy can convert non-Google Docs files to Google Docs files. Please be careful about this. I think that this is the reason for your current issue. In order to convert XLSX data to CSV data using Google Apps Script, it is required to do the following flow.
Convert XLSX data to Google Spreadsheet.
Convert Google Spreadsheet to CSV data.
Remove Google Spreadsheet.
When this flow is reflected in your script, it becomes as follows.
Modified script:
function makeCSV() {
var SourceFolder = DriveApp.getFolderById("1aoonhCebvI5DddvJVGTzBvWs2BPn_yXN");
var DestinationFolder = DriveApp.getFolderById("1LB0Em4vYFJV8vJIEiLt6Tg5pnzPATZEj");
var searchQuery = "mimeType='" + MimeType.MICROSOFT_EXCEL + "' or mimeType='" + MimeType.MICROSOFT_EXCEL_LEGACY + "'";
var sourceFiles = SourceFolder.searchFiles(searchQuery);
var now = new Date();
var properties = PropertiesService.getScriptProperties();
var cutoff_datetime = properties.getProperty('last_execution_time');
if (cutoff_datetime) cutoff_datetime = new Date(cutoff_datetime);
var token = ScriptApp.getOAuthToken();
while (sourceFiles.hasNext()) {
var sourceFile = sourceFiles.next();
if (!cutoff_datetime || sourceFile.getDateCreated() > cutoff_datetime) {
var fileId = sourceFile.getId();
var ssId = Drive.Files.copy({mimeType: MimeType.GOOGLE_SHEETS, parents: [{ id: "1LB0Em4vYFJV8vJIEiLt6Tg5pnzPATZEj" }]}, fileId).id;
var url = "https://docs.google.com/spreadsheets/export?exportFormat=csv&id=" + ssId;
var blob = UrlFetchApp.fetch(url, {headers: {authorization: "Bearer " + token}}).getBlob();
DestinationFolder.createFile(blob.setName(sourceFile.getName().split(".")[0] + ".csv"));
DriveApp.getFileById(ssId).setTrashed(true);
}
}
properties.setProperty('last_execution_time', now.toString());
}
When this script is run, the XLSX data is converted to Google Spreadsheet, and Google Spreadsheet is converted to CSV data. The CSV file is created to DestinationFolder folder.
Note:
This script used Drive API. So, please enable Drive API at Advanced Google services.
References:
Files: copy
fetch(url, params)
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.
}
}
}
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
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;