Save gmail attachment as google sheets in gdrive [duplicate] - google-apps-script

I know it is possible to convert excel files to Google Sheets using script and drive API, but I'm looking for script to convert the excel sheet and move the converted file to a different folder.
So the required steps are as follows:
Convert excel (.xls/.xlsx) to Google Sheet from FolderA.
Move converted file from FoldarA to FolderB.
Delete original excel file from FolderA
Hopefully step 3 avoids this, but avoid duplicating already converted file.
The excel files are being pasted into a local folder that is being synced to google drive, and the files are no larger than 3mb. The current script is as follows. This is converting the files but placing them in the root folder, and will duplicate the conversion when the script runs again.
function importXLS(){
var files = DriveApp.getFolderById('1hjvNIPgKhp2ZKIC7K2kxvJjfIeEYw4BP').searchFiles('title != "nothing"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name+'_converted',
key : ID
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
}
}

You want to create the converted Google Spreadsheet files to "FolderB".
You want to delete the XLSX files in "FolderA" after the files were converted.
You want to achieve above using Google Apps Script.
If my understanding correct, how about this modification? In this modification, I modified your script.
Modification points:
You can directly create the file to the specific folder using the property of parents in the request body.
You can delete the file using Drive.Files.remove(fileId).
Modified script:
Before you use this script, please enable Drive API at Advanced Google services.
function importXLS(){
var folderBId = "###"; // Added // Please set the folder ID of "FolderB".
var files = DriveApp.getFolderById('1hjvNIPgKhp2ZKIC7K2kxvJjfIeEYw4BP').searchFiles('title != "nothing"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = {
title : name+'_converted',
parents: [{id: folderBId}] // Added
};
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
// Drive.Files.remove(ID); // Added // If this line is run, the original XLSX file is removed. So please be careful this.
}
}
}
Note:
If the number of XLSX files is large, the execution time might be over 6 minutes.
About // Drive.Files.remove(ID);, when you run this script, please be careful. Because the original XLSX files are completely deleted when the script is run. So I commented this. At first, please test the script using sample files.
References:
Files: insert
Files: delete

Related

Is it possible to save an excel attachment as a "proper" google sheet file? [duplicate]

I know it is possible to convert excel files to Google Sheets using script and drive API, but I'm looking for script to convert the excel sheet and move the converted file to a different folder.
So the required steps are as follows:
Convert excel (.xls/.xlsx) to Google Sheet from FolderA.
Move converted file from FoldarA to FolderB.
Delete original excel file from FolderA
Hopefully step 3 avoids this, but avoid duplicating already converted file.
The excel files are being pasted into a local folder that is being synced to google drive, and the files are no larger than 3mb. The current script is as follows. This is converting the files but placing them in the root folder, and will duplicate the conversion when the script runs again.
function importXLS(){
var files = DriveApp.getFolderById('1hjvNIPgKhp2ZKIC7K2kxvJjfIeEYw4BP').searchFiles('title != "nothing"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name+'_converted',
key : ID
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
}
}
You want to create the converted Google Spreadsheet files to "FolderB".
You want to delete the XLSX files in "FolderA" after the files were converted.
You want to achieve above using Google Apps Script.
If my understanding correct, how about this modification? In this modification, I modified your script.
Modification points:
You can directly create the file to the specific folder using the property of parents in the request body.
You can delete the file using Drive.Files.remove(fileId).
Modified script:
Before you use this script, please enable Drive API at Advanced Google services.
function importXLS(){
var folderBId = "###"; // Added // Please set the folder ID of "FolderB".
var files = DriveApp.getFolderById('1hjvNIPgKhp2ZKIC7K2kxvJjfIeEYw4BP').searchFiles('title != "nothing"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = {
title : name+'_converted',
parents: [{id: folderBId}] // Added
};
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
// Drive.Files.remove(ID); // Added // If this line is run, the original XLSX file is removed. So please be careful this.
}
}
}
Note:
If the number of XLSX files is large, the execution time might be over 6 minutes.
About // Drive.Files.remove(ID);, when you run this script, please be careful. Because the original XLSX files are completely deleted when the script is run. So I commented this. At first, please test the script using sample files.
References:
Files: insert
Files: delete

Copying XLSX file to GSheet in Google Drive

I'm trying to copy over an XLSX sheet to an existing Gsheet, both are in the same GDrive folder. This script works when I run it as Drive.Files.insert() but that causes multiple version of the file to be created each time the script is run - so I switched it over to Drive.Files.update() like below....
function importXLS(){
var myFolder= "XXXXXXXXXX"; // Set the folder ID of "FolderB" if you want to copy over to a different folder
var files = DriveApp.getFolderById(myFolder).searchFiles('title = "XXXXX.xlsx"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = {
title : name + '_converted',
parents: [{'id': myFolder}],
supportsAllDrives: true
};
file = Drive.Files.update(newFile, xBlob, { //Originally using Drive.Files.insert() but was creating multiple versions. I want to overwrite the existing version.
convert: true, supportsAllDrives: true
});
}
}
}
But I'm getting the following error when this runs...
Exception: The mediaData parameter only supports Blob types for upload.
Any idea on what I'm doing wrong? This is my first time using Google Apps Script and javascript so I'm kinda flying blind here.
I believe your goal is as follows.
You have a folder in Google Drive. There are XLSX files and Google Spreadsheets in the folder.
You want to overwrite the Google Spreadsheet with the XLSX file by searching the filename.
Filename of the XLSX file is like XXXXX.xlsx.
Filename of the Google Spreadsheet file is like XXXXX.xlsx_converted.
Modification points:
In the case of Drive.Files.update, it is required to include the file ID of the target file.
In your script, the file ID of the target Spreadsheet is not retrieved.
The 2nd argument of Drive.Files.update is required to be the file ID. But, your script uses blob. I thought that this might be the reason for your current issue.
When these points are reflected in your script, how about the following modification?
Modified script:
function importXLS() {
var myFolder = "XXXXXXXXXX"; // Please set the folder ID.
var filename = "XXXXX.xlsx"; // Please set the filename of XLSX file.
var folder = DriveApp.getFolderById(myFolder);
var files = folder.searchFiles(`title="${filename}" and mimeType="${MimeType.MICROSOFT_EXCEL}" and trashed=false`);
while (files.hasNext()) {
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xlsx') > -1) {
var xBlob = xFile.getBlob();
var spreadsheetFileName = name + '_converted';
var spreadsheet = folder.searchFiles(`title="${spreadsheetFileName}" and mimeType="${MimeType.GOOGLE_SHEETS}" and trashed=false`);
if (spreadsheet.hasNext()) {
Drive.Files.update(null, spreadsheet.next().getId(), xBlob, { convert: true, supportsAllDrives: true });
} else {
var newFile = { title: spreadsheetFileName, parents: [{ 'id': myFolder }] };
file = Drive.Files.insert(newFile, xBlob, { convert: true, supportsAllDrives: true });
}
}
}
}
When this script is run, the XLSX file of XXXXX.xlsx is retrieved from the specific folder. And, Google Spreadsheet of the filename of XXXXX.xlsx_converted is searched from the same folder. When the Spreadsheet is found, the Spreadsheet is overwritten by the XLSX file. When the Spreadsheet is not found, a new Spreadsheet is created by converting the XLSX file.
Reference:
Files: update

How can i REPLACE a file with another file (if their name is the same) using 'Trash' ing in Google App Script?

I am accessing a list of folders from a shared drive.
In here, I am converting a few excel files into spreadsheet. My issue is to replace the old converted files with the new file. This is because every time i run the script the new converted file(with same name) keeps on multiplying in the same folder together with the old one.
Here is the code:
function ConvertFiles() {
var sheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var r= 2;
for(r= 2;r < sheet.getLastRow(); r++){
// Use getValue instead of getValues
var fileId = sheet.getRange(r,1).getValue();
var folderID = sheet.getRange(r,8).getValue();
var files = DriveApp.getFileById(fileId);
var name = files.getName().split('.')[0];
var blob = files.getBlob();
var newFile = {
// Remove '_converted' from name if existing to avoid duplication of the string before adding '_converted'
// This will allow to have newly converted file "replace" the old converted file properly
title: name.replace('_converted','') + '_converted',
parents: [{
id: folderID
}]
};
var destinationFolderId = DriveApp.getFolderById(folderID);
var existingFiles = destinationFolderId.getFilesByName(newFile.title);
// GOAL #1: To replace/update the old converted file into the latest one everytime the script runs (if it has the same filename)
// Find the file with same name of the file to be converted
while(existingFiles.hasNext()) {
// ID of the file with same converted name
var oldConvertedFileWithSameNameID = existingFiles.next().getId();
// Delete before writing
Drive.Files.remove(oldConvertedFileWithSameNameID);
//DriveApp.getFileById(oldConvertedFileWithSameNameID.getId()).setTrashed(true);
}
// Create new converted file then get ID
var newFileID = Drive.Files.insert(newFile, blob, { convert: true,supportsAllDrives: true }).id;
Logger.log(newFileID);
//var sheetFileID = newFileID.getId();
//var Url = "https://drive.google.com/open?id=" + sheetFileID;
var Url = "https://drive.google.com/open?id=" + newFileID;
// Add the ID of the converted file
sheet.getRange(r,9).setValue(newFileID);
sheet.getRange(r,10).setValue(Url);
}
}
My goal is
To replace the old converted file with the new one(if they have the same name) into the shared drive folder
To get to know how can i implement the setTrashed() inside the above code
I have tried using the Drive.Files.remove(oldConvertedFileWithSameNameID); but I am getting an error message GoogleJsonResponseException: API call to drive.files.delete failed with error: File not found:("fileid"). Then i saw an question on this [https://stackoverflow.com/questions/55150681/delete-files-via-drive-api-failed-with-error-insufficient-permissions-for-this]...so i guess that method is not suitable to implemented in shared folder.
So i how can i use setTrashed() method inside the above code?
I think you need to set the supportsAllDrives parameter:
Drive.Files.remove(oldConvertedFileWithSameNameID, {supportsAllDrives: true});
References:
Files:delete | Google Drive API | Google Developers - Parameters

Is there any way I can convert CSV files w/o avoid converting already converted files

Hi im absolute novice with google script in general, ive been tweaking around with this script i found from Bulk convert csv files in Google drive to Google Sheets:
function convert() {
var folder = DriveApp.getFolderById('folder id here');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
Drive.Files.copy({}, file.getId(), {convert: true});
}
}
and it works like a charm. the problem is that the this code indiscriminately convert every file in the said folder, including the converted file and source file. so if i run the script for the 2nd i would end up with a new copy of the converted file and another copy of the source file.
is there any way to work around this? i was thinking something along the lines of moving the converted files into a different folder and allow file overwriting to avoid copies.
thank you so much in advance.
How about this modification?
In this modification, I would like to propose the following workaround.
Workaround:
In this workaround, the mimeType of the source file is checked, and also, the description is given the copied source file. The description is used as the checker whether the file had been copied. By this, when the script is run for the 1st time, the CSV source files are converted to Google Spreadsheet. At that time, the description is added to the source files as copied. And, in the 2nd run, the files with the mimeType of CSV and the description has no value of copied are copied and converted. By this flow, the files which has been copied are not used after 2nd run.
When above workaround is reflected to your script, it becomes as follows.
Sample script:
function convert() {
var folder = DriveApp.getFolderById('folder id here');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.CSV && file.getDescription() != "copied") { // Added
file.setDescription("copied"); // Added
Drive.Files.copy({}, file.getId(), {convert: true});
}
}
}
Note:
When you have already used the description of the file, you can also use the property of the file.
If you want to copy the source CSV files every run, you can also use the following modified script. In this case, only the mimeType is checked.
function convert() {
var folder = DriveApp.getFolderById('folder id here');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.CSV) { // Added
Drive.Files.copy({}, file.getId(), {convert: true});
}
}
}
References:
getMimeType()
getDescription()
setDescription(description)

Download Folder as Zip Google Drive API

I currently have a Google App Script in Google Sheet that gives me the URL of a folder, which I can then use to download. Though it is an extra step I would like to remove, and get the URL of the zipped content directly.
Here's my code (google app script):
function downloadSelectedScripts() {
// ...
var scriptFiles = getScriptFiles(scriptFileNames)
var tempFolder = copyFilesToTempFolder(scriptFiles)
Browser.msgBox(tempFolder.getUrl())
}
function copyFilesToTempFolder(files) {
var tempFolder = DriveApp.getFolderById(FOLDERS.TEMP)
var tempSubFolder = tempFolder.createFolder('download_' + Date.now())
for (var i in files) {
var file = files[i]
file.makeCopy(file.getName(), tempSubFolder)
}
return tempSubFolder
}
You want to compress all files in a folder as a zip file.
The folder has no subfolders.
All files are only text files.
The total size of all files is less than 50 MB.
You want to retrieve the URL for downloading the zip file.
If my understanding is correct, how about this sample script? The flow of this script is as follows.
Retrieve folder.
Retrieve blobs of all files in the folder.
Compress blobs and retrieve a blob of zip.
Create a zip blob as a file.
Retrieve URL for downloading.
Sample script:
When you use this script, please set the folder ID of folder that you want to compress.
function myFunction() {
var folderId = "###"; // Please set the folder ID here.
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFiles();
var blobs = [];
while (files.hasNext()) {
blobs.push(files.next().getBlob());
}
var zipBlob = Utilities.zip(blobs, folder.getName() + ".zip");
var fileId = DriveApp.createFile(zipBlob).getId();
var url = "https://drive.google.com/uc?export=download&id=" + fileId;
Logger.log(url);
}
Result:
The direct link of the zip file is returned as follows.
https://drive.google.com/uc?export=download&id=###
Note:
In the current stage, unfortunately, the folders cannot be included in the zip data with Google Apps Script.
In this sample script, the filename of zip file is the folder name. So please modify it for your situation.
If you want to download the zip file without login to Google, please share the file.
Reference:
zip(blobs, name)