How do I create Spreadsheet inside a specific folder? - google-apps-script

Currently, based on certain parameters, I'm creating Spreadsheets using Apps Script via the following code -
function newFile() {
var number = '1';
var newFile = SpreadsheetApp.create("Roll " + number);
}
These new sheets however are being created at the root of Google Drive but instead, I want them to be created under a specific folder.
Unable to find any documentation for it. Any help would be appreciated.

You want to create a new Spreadsheet to the specific folder.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several answers.
Pattern 1:
In this pattern, your script is modified. After the new Spreadsheet was created to the root folder, the Spreadsheet is moved to the specific folder.
Sample script:
var folderId = "###"; // Please set the folder ID.
var number = '1';
var fileName = "Roll " + number;
var number = '1';
var newFile = SpreadsheetApp.create("Roll " + number);
var folder = DriveApp.getFolderById(folderId);
var file = DriveApp.getFileById(newFile.getId());
DriveApp.getFolderById("root").removeFile(file);
folder.addFile(file);
Pattern 2:
In this pattern, the new Spreadsheet is directly created to the the specific folder using Drive API. When you use this script, please enable Drive API at Advanced Google services.
Sample script:
var folderId = "###"; // Please set the folder ID.
var number = '1';
var fileName = "Roll " + number;
var file = Drive.Files.insert({title: fileName, mimeType: MimeType.GOOGLE_SHEETS, parents: [{id: folderId}]});
var newFile = SpreadsheetApp.openById(file.id);
References:
removeFile() of Class DriveApp
addFile() of Class DriveApp
Advanced Google services
Files: insert of Drive API
If I misunderstood your question and this was not the direction you want, I apologize.

Related

Google Apps Script - How to change the code to create Google Sheets file in active Google Drive Shared folder rather than root (My Drive) folder?

I have some code below that takes all the tabs (excluding 2 of them) in a Google Sheets file and creates independent Google Sheets files for each of them. Right now, they are saving by default in root folder (My Drive), but I would like them to be created in the same active folder as the file from which I call my Google Apps Script. Does anyone know how I can do that with the below code? I also want to avoid scenarios where it's created first in My Drive and then moved to the Shared Drive. The reason for this is because other people may run this code and I want to avoid an instance where the folder in My Drive needs to be updated in the code based on who runs this script.
The simplified version of my above paragraph for brevity: How can I adapt the below code so that the Google Sheets files that are created show up in the active Google Shared Drive folder? I will enabling the Drive API.
My Current Code:
function copySheetsToSS(){
var ss = SpreadsheetApp.getActive();
for(var n in ss.getSheets()){
var sheet = ss.getSheets()[n];
var name = sheet.getName();
if(name != 'ControlTab' && name != 'RawData'){
var alreadyExist = DriveApp.getFilesByName(name);
while(alreadyExist.hasNext()){
alreadyExist.next().setTrashed(true);
}
var copy = SpreadsheetApp.create(name);
sheet.copyTo(copy).setName(name);
copy.deleteSheet(copy.getSheets()[0]);
}
}
}
In your situation, when your script is modified, how about the following modification?
Modified script:
In this modification, Drive API is used. So, please enable Drive API at Advanced Google services.
function copySheetsToSS() {
var ss = SpreadsheetApp.getActive();
var folderId = DriveApp.getFileById(ss.getId()).getParents().next().getId();
for (var n in ss.getSheets()) {
var sheet = ss.getSheets()[n];
var name = sheet.getName();
if (name != 'ControlTab' && name != 'RawData') {
var alreadyExist = DriveApp.getFilesByName(name);
while (alreadyExist.hasNext()) {
alreadyExist.next().setTrashed(true);
}
var newSS = Drive.Files.insert({ title: name, mimeType: MimeType.GOOGLE_SHEETS, parents: [{ id: folderId }] }, null, { supportsAllDrives: true });
var copy = SpreadsheetApp.openById(newSS.id);
sheet.copyTo(copy).setName(name);
copy.deleteSheet(copy.getSheets()[0]);
}
}
}
In this modification, first, the parent folder of Spreadsheet is retrieved. And, in the loop, the new Spreadsheet is created to the specific folder using Drive API.
Note:
In this case, it is required to have the write permission of the folder. Please be careful about this.
References:
getFileById(id)
getParents()
Files: insert

Google script API - How to create a google doc in a particular folder

Basically this question is giving an answer for what I'd like to do:
Google script to create a folder and then create a Google Doc in that folder
But it's 5 years old, and I was wondering if there was an easier way now. In my case I have lots of existing folders and I want to create a particular file in each of them via a script that runs at intervals.
Thx.
EDIT:
Ok, the code below works fine (using a modified sample script 1 in the answer) when the folder 'test folder' is in a shared drive.
function testFunction() {
const notesFileName = 'test doc';
const folderName = 'test folder';
const query = "title = '" + folderName + "'";
// Find all folders that match the query.
var folders = DriveApp.searchFolders(query);
while (folders.hasNext()) {
// In all the sub-folders, of each found folder, create a file with the same name.
var folder = folders.next();
Logger.log("Found a folder: " + folder);
var subFolders = folder.getFolders();
while( subFolders.hasNext() ) {
var subFolder = subFolders.next();
Logger.log('Folder id: ' + subFolder.getId());
const doc = Drive.Files.insert({title: notesFileName, mimeType: MimeType.GOOGLE_DOCS, parents: [{id: subFolder.getId()}]}, null, {supportsAllDrives: true});
}
}
}
I believe your goal as follows.
You want to create new Google Document to the specific folders.
You have a lot of folders you want to create new Google Document. So you want to reduce the process cost of the script.
In this case, I would like to propose to create the new Google Document using Drive API. When Drive API is used, the creation of Google Document to each folder can run with the asynchronous process. The sample script is as follows.
Sample script 1:
Before you use this script, please enable Drive API at Advanced Google services. In this sample script, the new Google Documents are created to the specific folders in a loop.
function sample1() {
const titleOfDocument = "sample document";
const folderIds = ["### folder ID1 ###", "### folder ID 2 ###",,,];
const documentIds = folderIds.map(id => Drive.Files.insert({title: titleOfDocument, mimeType: MimeType.GOOGLE_DOCS, parents: [{id: id}]}).id);
console.log(documentIds)
}
In this script, the created Document IDs are returned.
If the process time of this script was long in your actual situation, please test the following sample script 2.
Sample script 2:
Before you use this script, please enable Drive API at Advanced Google services. In this sample script, the new Google Documents are created to the specific folders using the batch request of Drive API using a Google Apps Script library. By this, the tasks are run with the asynchronous process.
Please install the Google Apps Script library for using the batch request. Ref
function sample2() {
const titleOfDocument = "sample document";
const folderIds = ["### folder ID1 ###", "### folder ID 2 ###",,,];
const requests = {
batchPath: "batch/drive/v3",
requests: folderIds.map(id => ({
method: "POST",
endpoint: `https://www.googleapis.com/drive/v3/files`,
requestBody: {name: titleOfDocument, mimeType: MimeType.GOOGLE_DOCS, parents: [id]},
})),
accessToken: ScriptApp.getOAuthToken(),
};
const result = BatchRequest.EDo(requests); // Using GAS library
const documentIds = result.map(({id}) => id);
console.log(documentIds)
}
Note:
For above sample scripts, if you want to retrieve the folder IDs under the specific folder, you can also use for folderIds as follows.
const topFolderId = "### top folder ID ###";
const folders = DriveApp.getFolderById(topFolderId).getFolders();
const folderIds = [];
while (folders.hasNext()) {
folderIds.push(folders.next().getId());
}
By the way, in the current stage, in order to move the file, you can use moveTo(destination). Using this, the script of this can be modified as follows.
function createDoc(folderID, name) {
var folder = DriveApp.getFolderById(folderID);
var doc = DocumentApp.create(name);
DriveApp.getFileById(doc.getId()).moveTo(folder);
return doc;
}
References:
Files: insert of Drive API v2
Files: create of Drive API v3
BatchRequest

Create a Google Doc file directly in a Google Drive folder

How do I create a Google document in a Google Drive folder?
I know that I can create a file in a folder like this.
var folder = DriveApp.createFolder("A Folder")
folder.createFile("filename.file", "Some text")
But how I can create a document in a folder using Google Apps Script.
The other answer is correct but the file will exist in your folder AND in your "drive" folder (the root folder).
To avoid that, simply remove it from there !
code :
var doc = DocumentApp.create('Document Name'),
docFile = DriveApp.getFileById( doc.getId() );
DriveApp.getFolderById('0B3°°°°°°°1lXWkk').addFile( docFile );
DriveApp.getRootFolder().removeFile(docFile);
With document it's a bit different, you first create it then move to the folder:
var doc = DocumentApp.create('Document Name'),
docFile = DriveApp.getFileById( doc.getId() );
DriveApp.getFolderById(foldId).addFile( docFile );
This is how to create a new Google Doc in a specific folder. When the Doc is created, the mime type must be set.
Note that this code does NOT first create a Doc file, move it, and then delete the file in the Root Drive. This code creates a new Google Doc type file directly in a folder.
You will need to use the Advanced Drive API. It must be enabled in two places.
From the code editor choose "Resources" and then choose, "Advanced Google services"
Click the button for "Drive API" so that it is ON.
Click the link: Google Cloud Platform API Dashboard.
Search Drive API
Choose Google Drive API from search list
Enable the Drive API
Code:
function myFunction(e) {
var doc,fileResource,folder,ID_of_newFile,multipleFolders,newFile,
newDocName,rng,sh,ss,ssFile,ssID;
var name = e.values[1];
var kantoor = e.values[2];
newDocName = 'Sleuteloverdracht ' + name;//Set the name of the new file
rng = e.range;//Get range in the spreadsheet that received the data
sh = rng.getSheet();//Get sheet tab
ss = sh.getParent();//Get spreadsheet
ssID = ss.getSheetId();//Get file ID of spreadsheet - Integer
ssFile = DriveApp.getFileById(ssID);//Get the spreadsheet file in order to get the
//folder to put the new file in
multipleFolders = ssFile.getParents();//Get all parent folders of the spreadsheet file
folder = multipleFolders.next();//Get the folder of the spreadsheet
fileResource = {
'title': newDocName,
"parents": [{'id':folder.getId()}], //<--By setting this parent ID to the
//folder's ID, it creates this file in the correct folder
'mimeType': 'application/vnd.google-apps.document'
};
newFile = Drive.Files.insert(fileResource);//Create the new document file
// directly into the same folder as the spreadsheet
ID_of_newFile = newFile.getId();
//Logger.log(ID_of_newFile)
doc = DocumentApp.openById(newFile.getId());//Open the new file as a Google document
var body = doc.getBody();
body.appendParagraph('Sleuteloverdracht ' + name);
body.appendParagraph('Uw naam is '+ name + '\n' +
'U heeft de sleutel van kantoor '+ kantoor);
doc.saveAndClose();
}
Serge insas's answer helped me, but the methods are now deprecated in 2021. Here is what worked for me.
var folder = 'Your Folder Id'
var title = 'Your File Name'
var doc = DocumentApp.create(title);
docFile = DriveApp.getFileById(doc.getId());
docFile.moveTo(folder);
To add to #Kriggs answer.
To remove from the root folder:
DriveApp.getRootFolder().removeFile(file)
Otherwise, it will be in the root level and the new location.
var folder = DriveApp.createFolder ("A Folder");
var file = DriveApp.createFile ("filename.file", "Some text");
file.moveTo (folder);
You can also use the Drive App to create a copy of a Google document (e.g. a template)
use this:
DriveApp.getFileById(templateFileId).makeCopy(name, destination);

How to Create a Spreadsheet in a particular folder via App 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)

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 )