我在 Google Drive 文件夹中有一个文件夹,其中包含几个文件。我想制作一个 Google Apps 脚本,它将压缩该文件夹中的所有文件并在同一文件夹中创建 zip 文件。
我找到了一个有Utilities.zip()
功能的视频,但没有 API 参考。我该如何使用它?提前致谢。
我在 Google Drive 文件夹中有一个文件夹,其中包含几个文件。我想制作一个 Google Apps 脚本,它将压缩该文件夹中的所有文件并在同一文件夹中创建 zip 文件。
我找到了一个有Utilities.zip()
功能的视频,但没有 API 参考。我该如何使用它?提前致谢。
实际上它比这更容易。文件已经是 Blob(任何具有 getBlob() 的东西都可以传递给任何需要 Blob 的函数)。所以代码看起来像这样:
var folder = DocsList.getFolder('path/to/folder');
folder.createFile(Utilities.zip(folder.getFiles(), 'newFiles.zip'));
此外,如果您在文件夹中有多个具有相同名称的文件,它将不起作用... Google Drive 文件夹支持,但 Zip 文件不支持。
要使其适用于具有相同名称的多个文件:
var folder = DocsList.getFolder('path/to/folder');
var names = {};
folder.createFile(Utilities.zip(folder.getFiles().map(function(f){
var n = f.getName();
while (names[n]) { n = '_' + n }
names[n] = true;
return f.getBlob().setName(n);
}), 'newFiles.zip'));
正如DocsList
已弃用的那样,您可以使用以下代码压缩包含文件和子文件夹的整个文件夹,并保持其结构:
var folder = DriveApp.getFolderById('<YOUR FOLDER ID>');
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
getBlobs
函数将文件夹中的所有文件组成一个数组,并将每个文件名更改为其相对路径,以在压缩时保持结构。
要压缩包含多个同名项目的文件夹,请使用此getBlob
函数:
function getBlobs(rootFolder, path) {
var blobs = [];
var names = {};
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
var n = file.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
blobs.push(file.setName(path+n));
}
names = {};
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var n = folder.getName();
while(names[n]) { n = '_' + n }
names[n] = true;
var fPath = path+n+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
我能够使用@Hafez 发布的代码,但我需要修改它,因为它不适合我。我添加了前三行,因为我需要文件夹 ID,它是一个字符串值,而不是文件夹的名称。
var folderName = DriveApp.getFoldersByName("<folderName>");
var theFolder = folderName.next();
var folderID =theFolder.getId();
var folder = DriveApp.getFolderById(folderID);
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName()+'.zip');
folder.getParents().next().createFile(zipped);
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName()+'/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}
我遇到的唯一奇怪的事情是,当我运行脚本时它说TypeError: Cannot call method "getFiles" of undefined. (line 10, file "Code")
. 当我碰巧看到这个脚本所在的地方时,还有 5 个完整的 zip 文件。它有效,但我仍然收到该错误。奇怪......但这段代码对我有用。感谢这个线程上的每个人。干杯!
确实没有 API 参考。您可以在 Apps Script issue tracker上打开有关此问题的问题请求。但是从代码完成显示的内容推断,这是我的理解:
var folder = DocsList.getFolder('path/to/folder');
var files = folder.getFiles();
var blobs = [];
for( var i in files )
blobs.push(files[i].getBlob());
var zip = Utilities.zip(blobs, 'newFiles.zip');
folder.createFile(zip);
但是我没有测试过这段代码,所以我不知道它是否可以工作。此外,它可能仅适用于未转换为 Google 格式的文件,或者可能仅适用于这些文件或其中的一部分。好吧,如果您尝试一下并找到一些东西,请在此处与我们分享。您肯定会面临的一个限制是文件大小,如果 zip 文件变得“太大”,它可能无法正常工作......是的,您也必须测试这个限制。
如果 Hafez 解决方案没有成功,并且您收到此错误
TypeError:无法读取未定义的属性“getFiles”
尝试这样做
/**
* Creates a zipFile of the mentioned document ID and store it in Drive. You can search the zip by folderName.zip
*/
function createAndSendDocument() {
var files = DriveApp.getFolderById("DOCUMENT ID CAN BE FIND IN THE URL WHEN A DOCUMENT IS OPENED");
var folder = files;
var zipped = Utilities.zip(getBlobs(folder, ''), folder.getName() + '.zip');
folder.getParents().next().createFile(zipped);
}
function getBlobs(rootFolder, path) {
var blobs = [];
var files = rootFolder.getFiles();
while (files.hasNext()) {
var file = files.next().getBlob();
file.setName(path+file.getName());
blobs.push(file);
}
var folders = rootFolder.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
var fPath = path+folder.getName() + '/';
blobs.push(Utilities.newBlob([]).setName(fPath)); //comment/uncomment this line to skip/include empty folders
blobs = blobs.concat(getBlobs(folder, fPath));
}
return blobs;
}