How to Create a Spreadsheet in a particular folder via App Script - google-apps-script

Can anybody help me out,
I want to create a Spreadsheet through App Script in a particular folder. How to do that.
Presently I am doing as follow:
var folder = DocsList.getFolder("MyFolder");
var sheet = SpreadsheetApp.create("MySheet");
var file = DocsList.getFileById(sheet.getId());
file.addToFolder(folder);
file.removeFromFolder(file.getParents()[0]);
It is not working.......

As suggested by #Joshua, it's possible to create a Spreadsheet (in a specific folder) with the Advanced Drive Service (you'll need to activate this if you haven't already, by going into Services +, find Drive API and click Add).
var name = 'your-spreadsheet-name'
var folderId = 'your-folder-id'
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var fileJson = Drive.Files.insert(resource)
var fileId = fileJson.id
No need to move files around with this method !

folder = DriveApp.getFolderById("FOLDER_ID")
var ss = SpreadsheetApp.create("SPREADSHEET_NAME")
DriveApp.getFileById(ss.getId()).moveTo(folder);
You may use the above code to achieve the same without using advanced drive services

Since you can no longer create Google Docs (Docs or SpreadSheets) using DriveApp, nor use addToFolder because DocList is deprecated. There is only one way to create or "move" Google Docs or Google SpreadSheets..
//"Move" file to folder-------------------------------//
var fileID = '12123123213321'
var folderID = '21321312312'
var file = DriveApp.getFileById(fileID).getName()
var folder = DriveApp.getFolderById(folderID)
var newFile = file.makeCopy(file, folder)
//Remove file from root folder--------------------------------//
DriveApp.getFileById(fileID).setTrashed(true)
As you can see this DOES NOT move the file, it makes a copy with the same name in the folder you want and then moves the original file to the trash. I'm pretty sure there is no other way to do this.

The other answer is a bit short (and not very explicit).
While your approach is logic and should work if you replace
file.removeFromFolder(file.getParents()[0]);
with
file.removeFromFolder(DocsList.getRootFolder());
there is a better way to do the same job using the new Drive app and the Folder Class, Folder has a method to create a file and you can specify the file type using the mimeType enum.
Code goes like this :
function myFunction() {
var folders = DriveApp.getFoldersByName('YOUR FOLDER NAME'); // replace by the right folder name, assuming there is only one folder with this name
while (folders.hasNext()) {
var folder = folders.next();
}
folder.createFile('new Spreadsheet', '', MimeType.GOOGLE_SHEETS); // this creates the spreadsheet directly in the chosen folder
}

In July 27, 2020 there have been these updates:
The File class now has the following methods:
file.getTargetId(): Gets a shortcut's file ID.
file.getTargetMimeType(): Returns the mime type of the item a shortcut points to.
file.moveTo(destination): Moves a file to a specified destination folder.
The Folder class now has the following methods:
folder.createShortcut(targetId): Creates a shortcut to the provided Drive item ID, and returns it.
folder.moveTo(destination): Moves an item to the provided destination folder.
The following Folder class methods have been deprecated:
addFile(File)
addFolder(Folder)
removeFile(File)
removeFolder(Folder)
https://developers.google.com/apps-script/releases/#july_27_2020
So you can create a Spreadsheet file in a folder using file.moveTo(destination) method:
function createSpreadSheetInFolder(ss_new_name, folder_dest_id) {
var ss_new = SpreadsheetApp.create(ss_new_name);
var ss_new_id = ss_new.getId();
var newfile = DriveApp.getFileById(ss_new_id);
newfile.moveTo(DriveApp.getFolderById(folder_dest_id))
return ss_new_id;
}
var file_name = 'SPREADSHEET NAME';
var folder_id = 'DESTINATION FOLDER ID';
var new_ssId = createSpreadSheetInFolder(file_name, folder_id)

You can create a spreadSheet and then add it to the folder.
function createSpreadSheetInFolder(name,folder){
var ss = SpreadsheetApp.create(name);
var id = ss.getId();
var file = DriveApp.getFileById(id);
folder.addFile(file);
return ss;
}
folderId='your_folder_id'
name='my_new_ss'
folder=DriveApp.getFolderById(folderId)
createSpreadSheetInFolder(name,folder)
By using the folder.addFile method there's no need to use a temp file (no need to duplicate and remove file). Pretty straightforward !

I finally got the answer to my question. The following works
var file = DocsList.getFileById(sheet.getId());
var folder = DocsList.getFolder("MyFolder");
file.addToFolder(folder);
// remove document from the root folder
folder = DocsList.getRootFolder();
file.removeFromFolder(folder);

What is not working? Use getRootFolder in the last line.

Creating a new spreadsheet in a file can be done using this link as a reference.
createFile(name, content, mimeType)
Therefore using the enum MimeType we can do:
var folder = DriveApp.getFolderById("your-folder-id");
folder.createFile("My File Name","",MimeType.GOOGLE_SHEETS)

Related

Create a new folder and copy file into it Google App Scripts [duplicate]

Is there a way to create a google app script to create a new folder in Google Drive that is NOT IN THE ROOT FOLDER? A script to move a folder in the root to a particular folder will also do.
var parentFolder = DriveApp.getFolderById(parentFolderId);
var newFolder = parentFolder.createFolder("My New Folder Name");
var parentFolder=DriveApp.getFolderById(DriveApp.getRootFolder().getId());
var newFolder=parentFolder.createFolder("name folder")
If you are going to need the folder ID to let's say move or create a file there you can do the following.
var parentFolder = DriveApp.getFolderById(parentFolderId);
var newFolderID = parentFolder.createFolder("New Folder Name").getId();
Then you can do this
DriveApp.getFolderById(newFolderID);
The folder object has a createFolder method, see doc here.
so you should simply get the folder you want and create the new one from there.
getFolderById seems to be removed.
Try this:
function createFolder(parentFolderName)
{
var folders = DriveApp.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
if(parentFolderName == folder.getName())
folder.createFolder("Folder Name");
}
}

Can I use IMPORTRANGE on a Google Drive folder?

This code works for me if I am importing two sheets:
={IMPORTRANGE("Sheet1Key","SheetName!A2:A500");IMPORTRANGE("Sheet2Key","SheetName!A2:A500")}
However, I have multiple sheets, all in the same folder, all with the data in the first sheet and all with the data in the same cells.
Is it possible to somehow either import from a folder or somehow add the IDs or names of all files within that folder automatically?
I am not sure what you mean by import all the files within that folder automatically. But what you could do is use the following code that I made a while ago. (You need to make it under scripts.google.com and you need to run the code)
The only thing you would need to change is the folder name where I wrote “type name of folder”
function listFolderContents() {
var foldername = 'type name of folder';
var folderlisting = 'URL listing for folder ' + foldername;
var folders = DriveApp.getFoldersByName(foldername)
var folder = folders.next();
var contents = folder.getFiles();
var ss = SpreadsheetApp.create(folderlisting);
var sheet = ss.getActiveSheet();
sheet.appendRow( ['name', 'link'] );
var file;
var name;
var link;
var row;
while(contents.hasNext()) {
file = contents.next();
name = file.getName();
link = file.getUrl();
sheet.appendRow( [name, link] );
}
};
It will create a google spreadsheet called “URL listing for folder (name of folder) located inside the folder you are trying to get the files for. The spreadsheet will contain an array of all the file URL’s. It should be relatively easier to create the import range given the URL’s. You may be able to pick my code apart and use parts that help you with your goal. Hope this helps.
You just need to use an array:
=query(arrayformula({importrange(sheet1!A1:Z100);importrange(sheet2!A1:Z100)}), "SELECT *",1)
This does assume that all data is structured the same.

Move Folder Using App Script

So i'm brand new to JS and trying to build a program for internal operation at the company I work for. Below is the first bit of my code. I have a created a google form, and set a trigger so that when the submit button is clicked the below code will start. The trigger works and the first two functions work, but I cannot seem to get the Karrie folder to move from the root to the sub folder id (I do have the correct ID but omitted it from this post). Maybe I'm doing this all backwards so any help would be appreciated.
// Create Karrie Folder In Root
function start() {
var sourceFolder = "Property Template";
var targetFolder = "Karrie";
var source = DriveApp.getFoldersByName(sourceFolder);
var target = DriveApp.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target);}}
// Adds Property data to Karrie Folder
function copyFolder(source, target) {
var folders = source.getFolders();
var files = source.getFiles();
while(files.hasNext()) {
var file = files.next();
file.makeCopy(file.getName(), target);}
// Adds Photo Folders to Karrie Folder
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var targetFolder = target.createFolder(folderName);
copyFolder(subFolder, targetFolder);}}
// Moves Karrie folder to propertie folder
function MoveFiles(){
var files = DriveApp.getFolderByName("Karrie");
var destination = DriveApp.getFolderById("ID NA");
destination.addFolder(files);}
Debugger
I understood that MoveFiles() in your script doesn't work. If my understanding is correct, how about this modification?
Modification points :
In order to move a folder, it required to move the parent of the folder.
But when addFolder() is used to the folder, the folder has 2 parents.
So original parent has to be removed.
There is no getFolderByName(). Please use getFoldersByName().
Modified script :
function MoveFiles(){
var folder = DriveApp.getFoldersByName("Karrie").next();
var destination = DriveApp.getFolderById("ID NA");
destination.addFolder(folder);
folder.getParents().next().removeFolder(folder);
}
Note :
In this script, The folder and parent of "Karrie" supposes only one in the Google Drive, respectively.
References :
getFoldersByName()
addFolder()
removeFolder()
If I misunderstand your question, please tell me. I would like to modify it.
Edit 1 :
When you run this function, does the ID of Logger.log(r) show the folderId of "Karrie"?
function sample() {
var r = DriveApp.getFoldersByName("Karrie").next().getId();
Logger.log(r)
}
Edit 2 :
Please confirm and consider the following points.
Confirm the folder name and the existence of the folder again.
Run sample() and confirm folder ID of "Karrie".
Confirm whether there are no functions with the same name.
Can I ask you the folder ID of "Karrie"? If you cannot retrieve the folder ID using DriveApp.getFoldersByName("Karrie").next().getId(), I propose to use directly the folder ID of "Karrie".
Updated on March 30, 2022:
In the current stage, the files and folders can be moved using moveTo. Ref This method has added on July 27, 2020. When moveTo is used, the above script can be modified as follows.
function MoveFiles(){
var folder = DriveApp.getFoldersByName("Karrie").next();
var destination = DriveApp.getFolderById("ID NA");
folder.moveTo(destination);
}
Reference:
moveTo(destination) of Class Folder
As of 2020, the easier way I found to move a file is to use this function:
function moveToFolder(file, sourceFolder, destFolder) {
var file = DriveApp.getFileById(file.getId());
destFolder.addFile(file);
sourceFolder.removeFile(file);
}
Because of the first line, you can convert your Spreadsheet, Google Form, Document or others Google objects into a File.
Then we just use methods of the Folder class : https://developers.google.com/apps-script/reference/drive/folder
Notes:
If you created your file by using .create() your sourceFolder will be DriveApp.getRootFolder().
If you have multiple files to move, just iterate over them.

create a Google spreadsheet in a particular folder

this question teaches how to adjust the folders of a file to move it into a particular folder, and out of the root.
It also suggests using folder.createFile to create it directly in the desired folder... but it appears createFile only applies to Docs... is there a way to create a spreadsheet directly in a particular folder?
Since DocsList is deprecated, currently the following solution works:
var folder=DriveApp.getFoldersByName(folderName).next();//gets first folder with the given foldername
var file=SpreadsheetApp.create(fileName);
var copyFile=DriveApp.getFileById(file.getId());
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
Create spreadsheets using Apps Script does not work with regular Google accounts and Google Apps Standard Edition accounts. However, you can always make a copy of a dummy spreadsheet and then modify it accordingly using Google Apps Script. Here is a sample code.
function createSpreadsheetInfolder() {
var dummySS = DocsList.getFileById('ID of dummy SS');
var myCopy = dummySS.makeCopy('My new file');
//Get your target folder
var folder = DocsList.getFolder('ID or path of folder');
myCopy.addToFolder(folder);
}
The answers already given don't seem to work, maybe they're outdated.
Here's my answer (worked for me).
var folders=DriveApp.getFoldersByName("existingFolder");
while (folders.hasNext()) {
var folder = folders.next();
var file=SpreadsheetApp.create("the file that must be in a folder");
var copyFile=DriveApp.getFileById(file.getId());
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
}
Admittedly, my answer is derived from the previous ones, none of which did exactly what I needed. This function has been tested with current Google Apps Script and spreadsheet documents. With duplicate folder names it will work, but move the file to the first folder returned by the API.
// Arguments are a file object and a folder name.
function moveFileToFolder(file, folderName)
{
var folders = DriveApp.getFoldersByName(folderName);
var copyFile = DriveApp.getFileById(file.getId());
if (folders.hasNext()) {
var folder = folders.next();
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
}
}
Now it is possible to create Google spreadsheet in a specific folder.
For that you need to use advanced drive service v2. Enable it from Advanced Services menu in google app script editor.
var oFile = placeGoogleSpreadsheetInSpecificFolder("my file", "target folder id");
var oSpreadsheet = SpreadsheetApp.open(DriveApp.getFileById(oFile.getId()));
function placeGoogleSpreadsheetInSpecificFolder(sSpreadsheetName, sTargetFolderId) {
var oGeneratedFile = Drive.Files.insert({
"mimeType": "application/vnd.google-apps.spreadsheet",
"parents": [{
id: sTargetFolderId
}],
"title": sSpreadsheetName
});
return oGeneratedFile;
}
This solution worked perfectly fine for me.
This code works for me, I think there is no way to avoid the "remove from root" step, at least not that I know.
function createSpreadsheet() {
var folder = DocsList.getFolder('GAS');// this value as test for me
var root = DocsList.getRootFolder()
var newFileId = SpreadsheetApp.create('testNewSS').getId();// this defines the name of the new SS
var newFile = DocsList.getFileById(newFileId); // begin the 'move to folder process'
newFile.addToFolder(folder);
newFile.removeFromFolder(root);// had to do it in 2 separate steps
}
This question has beeen answerd in.
https://stackoverflow.com/a/19610700
It is a nice solustion.
folder.createFile("name", '',MimeType.GOOGLE_SHEETS);
using anything but a empty string leaves me with a error.
Just a 'heads up' for people who are reading this old answers like me. The most solutions are already deprecated. You have to use "moveTo" and you will not need to remove from root-directions or something else.
Have a look at this link for more details.
My solution to do so:
/**
* function createSS
* #description: Creates a new SpreadSheet with imported values and directly in provided folder
* #param {string} ssName name of SpreadSheet
* #param {object} sheetData values as range
* #param {object} ssFolder reference to a folder
*/
function createSS(ssName, sheetData, ssFolder = false){
var ss = SpreadsheetApp.create(ssName);
ss.setSpreadsheetLocale("de");
if(ssFolder){
// Move to provided folder
var file = DriveApp.getFileById(ss.getId());
file.moveTo(ssFolder);
}
var sheet = ss.getActiveSheet();
sheet.getRange(1, 1, sheetData.length, sheetData[0].length).setValues(sheetData);
return sheet;
}
Example with folder assignment:
var folders = DriveApp.getFileById(ssFileId).getParents();
var folder = folders.next();
// add new file (directly in correct folder)
var sourceSheet = createSS(newFileName, relevantValues, folder);
( This is only working this way, if you're sure your file is in 1 folder only. Otherwise, do it with .hasNext() and a loop )

Adding File to a Folder

I'm trying to relocate newly created Google Docs file to a folder within google drive (using Google Apps).
var newFile = DocumentApp.create('New File');
var newFileID = Docs.getFileById(newFile);
var newFileRelocated = newFileID.addToFolder(newFolder);
And I'm getting "Cannot find method addToFolder(. (Line ...)". What am I doing wrong? They method drops down as an option when I'm writing it and still it cannot find it.
It's likely that your newFolder is not what's expected. Is it a string? Where you defined it?
Anyway, the parameter expected in addToFolder must be a Folder object you got using some other method in DocsList. e.g. DocsList.getFolder("/path/to/folder") or DocsList.getFolderById("folder-id") and so on.
There seems to be other "inconsistencies" with your code, I'll paste what I you're trying to do:
var newDoc = DocumentApp.create('New Google Doc');
//a DocumentApp file and a DocsList file are not the same object, although they may point to the same Google Doc
var newFile = DocsList.getFileById(newDoc.getId());
var folder = DocsList.getFolder("/path/to/folder"); //I'm assuming the folder already exists
newFile.addToFolder(folder);
The logic of this is not exactly as you tried...
here is a working example :
function myFunction() {
var newFile = DocumentApp.create('New File');
var newFileID = newFile.getId()
var newFolder = DocsList.createFolder('test Folder')
DocsList.getFileById(newFileID).addToFolder(newFolder)
}
Just to add to this, I recently dealt with this issue.
I noticed the default location is to store the DocsList.create() file in the root folder (aka My Drive).
This could lead to a real headache if you were doing lots of files.
I added this as the line after the .addToFolder()
newFile.removeFromFolder(DocsList.getRootFolder());
The following function is a simple google script to pass in an image URL.
function fetchImageToDrive_(imageUrl)
{
//Fetch image blob
var imageBlob = UrlFetchApp.fetch(imageUrl).getBlob();
//Create image file in drive
var folder = DocsList.getFolder('test Folder');
folder.createFile(imageBlob);
}