【问题标题】:List every file and folder of a shared drive in a spreadsheet with Apps Script使用 Apps 脚本在电子表格中列出共享云端硬盘的每个文件和文件夹
【发布时间】:2022-10-07 05:53:11
【问题描述】:

我发现一个脚本可以完美地适用于我的驱动器,我想适应它也支持共享驱动器。

    function onOpen() {
  var SS = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();
  ui.createMenu(\'List Files/Folders\')
    .addItem(\'List All Files and Folders\', \'listFilesAndFolders\')
    .addToUi();
};

function listFilesAndFolders(){
  var folderId = Browser.inputBox(\'Enter folder ID\', Browser.Buttons.OK_CANCEL);
  if (folderId === \"\") {
    Browser.msgBox(\'Folder ID is invalid\');
    return;
  }
  getFolderTree(folderId, true); 
};

// Get Folder Tree
function getFolderTree(folderId, listAll) {
  try {
    // Get folder by id
    var parentFolder = DriveApp.getFolderById(folderId);
    
    // Initialise the sheet
    var file, data, sheet = SpreadsheetApp.getActiveSheet();
    sheet.clear();
    sheet.appendRow([\"Full Path\", \"Name\",\"Type\" ,\"Date\", \"URL\", \"Last Updated\", \"Description\", \"Size\",\"Owner Email\"]);
    
    // Get files and folders
    getChildFolders(parentFolder.getName(), parentFolder, data, sheet, listAll);
  } catch (e) {
    Logger.log(e.toString());
  }
};

// Get the list of files and folders and their metadata in recursive mode
function getChildFolders(parentName, parent, data, sheet, listAll) {
  var childFolders = parent.getFolders();
 
  // List folders inside the folder
  while (childFolders.hasNext()) {
    var childFolder = childFolders.next();
    var folderId = childFolder.getId();
    data = [ 
      parentName + \"/\" + childFolder.getName(),
      childFolder.getName(),
      \"Folder\",
      childFolder.getDateCreated(),
      childFolder.getUrl(),
      childFolder.getLastUpdated(),
      childFolder.getDescription(),
      childFolder.getSize()/1024,
      childFolder.getOwner().getEmail()
    ];
    // Write
    sheet.appendRow(data);
    
    // List files inside the folder
    var files = childFolder.getFiles();
    while (listAll & files.hasNext()) {
      var childFile = files.next();
      data = [ 
        parentName + \"/\" + childFolder.getName() + \"/\" + childFile.getName(),
        childFile.getName(),
        \"Files\",
        childFile.getDateCreated(),
        childFile.getUrl(),
        childFile.getLastUpdated(),
        childFile.getDescription(),
        childFile.getSize()/1024,
        childFile.getOwner().getEmail(),
      ];
      // Write
      sheet.appendRow(data);
    }
    // Recursive call of the subfolder
    getChildFolders(parentName + \"/\" + childFolder.getName(), childFolder, data, sheet, listAll);  
  }
};

老实说,我仍然不完全了解如何

{supportsAllDrives: true}

有效,但我会假设它正是缺少的。

我一直在尝试获取有关它的更多信息,但我发现的内容对我来说并不完全有用,也不是关于如何使用它的完整说明。

我对 Apps 脚本非常陌生,但我正在尽我所能制作完全可操作的代码或至少理解它,所以如果有人能将我链接到任何关于它的好页面,我将不胜感激。

  • 您是否尝试过建议的解决方案?
  • 是的,我实际上已经回复了 Tanaike,但评论不知何故被删除了。除了所有者电子邮件之外,他的答案有效,并且由于路径的编码方式,子文件夹中的子文件夹路径存在问题。通用代码很好,但是速度很慢,以至于对于超过 800 个文件都无法使用,尤其是如果将这些文件放在子文件夹中,因为它如何循环遍历文件夹和 appendRow。我做了一些相当大的改变,以摆脱未使用的代码并使其更快。我会发布结果,甚至可能看看是否有人有任何建议。
  • 出色地。接受正确答案很重要。这样每个人都会看到问题是如何解决的(甚至是部分解决的)。至于其余的,如果有解决方法,直接询问@Tanaike 是有意义的。 (如果您在评论中的昵称前添加@,它会将评论发送给提及的成员)

标签: google-apps-script google-sheets google-drive-shared-drive


【解决方案1】:

我有一个功能可以将信息复制到我的工作表中,它只需要一个文件夹。您可以根据需要进行修改:

启动功能:

function AddDataValidation(){
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName('Sheet0');  
  const folder = DriveApp.getFolderById("folder id");
  getFnF(folder);
}

递归函数:

var level = 1;
function getFnF(folder = DriveApp.getRootFolder()) {
  const ss = SpreadsheetApp.getActive();//active spreadsheet
  const sh = ss.getSheetByName('Sheet0')//change sheet name
  const files = folder.getFiles();
  sh.getRange(sh.getLastRow() + 1, level).setValue(folder.getName()).setFontWeight('bold');
  if (files.hasNext()) {
    sh.getRange(sh.getLastRow() + 1, level).setValue('Files:');
  }
  while (files.hasNext()) {
    let file = files.next();
    let firg = sh.getRange(sh.getLastRow() + 1, level + 1);
    firg.setValue(Utilities.formatString(file.getName()));
  }
  const subfolders = folder.getFolders()
  while (subfolders.hasNext()) {
    let subfolder = subfolders.next();
    level++;
    getFnF(subfolder);
  }
  level--;
}

共享驱动器中的文件夹:

function getFoldersInASharedFolder() {
  let tr = [];
  let token = '';
  let page = 0;
  do {
    let r = Drive.Files.list({ corpora: 'drive', includeItemsFromAllDrives: true, supportsTeamDrive: true, supportsAllDrives: true, driveId: "0AAc6_2qyI7C0Uk9PVA", pageToken: token,q: "mimeType = 'application/vnd.google-apps.folder'" });
    let obj = JSON.parse(r);
    tr.push(obj)
    token = obj.nextPageToken
  } while (token != null)

  let folder = DriveApp.getFolderById(gobj.globals.testfolderid);
  folder.createFile(`SharedDriveList ${Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss")}`, JSON.stringify(tr), MimeType.PLAIN_TEXT);

  let html = '<style>td,th{border:1px solid black;font-size: 16px;}</style><table><tr><th>Title</th><th>Id</th><th>Path</th></tr>';
  tr.forEach((o, i) => {
    o.items.forEach(item => {
      if (item.mimeType = "application/vnd.google-apps.folder") {
        html += `<tr><td>${item.title}</td><td>${item.id}</td><td>${getPathAllDrivesFromId(item.id)}</td></tr>`;
      }
    })
  });
  html += '</table><input type="button" value="exit" onclick="google.script.host.close()" />';
  SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(html).setHeight(500).setWidth(1200), `Foldersl in: ${JSON.parse(Drive.Drives.get("0AAc6_2qyI7C0Uk9PVA")).name}`);
}

【讨论】:

  • 嘿库珀,谢谢它对我很有效。一个小问题。如何将上次修改日期添加到下一列?
【解决方案2】:

{supportsAllDrives: true} 用于 Drive API。但是,幸运的是,在现阶段,当使用文件ID和文件夹ID时,可以使用Drive服务(DriveApp)检索共享驱动器中的文件和文件夹。但不幸的是,无法检索文件和文件夹的所有者。我认为这可能是您当前的放映脚本问题的原因。如果我的理解是正确的,那么下面的修改呢?

从:

data = [ 
  parentName + "/" + childFolder.getName(),
  childFolder.getName(),
  "Folder",
  childFolder.getDateCreated(),
  childFolder.getUrl(),
  childFolder.getLastUpdated(),
  childFolder.getDescription(),
  childFolder.getSize()/1024,
  childFolder.getOwner().getEmail()
];

至:

var ownerOfFolder = childFolder.getOwner();
data = [ 
  parentName + "/" + childFolder.getName(),
  childFolder.getName(),
  "Folder",
  childFolder.getDateCreated(),
  childFolder.getUrl(),
  childFolder.getLastUpdated(),
  childFolder.getDescription(),
  childFolder.getSize()/1024,
  ownerOfFolder ? ownerOfFolder.getEmail() : ""
];

另外,请进行如下修改。

从:

data = [ 
  parentName + "/" + childFolder.getName() + "/" + childFile.getName(),
  childFile.getName(),
  "Files",
  childFile.getDateCreated(),
  childFile.getUrl(),
  childFile.getLastUpdated(),
  childFile.getDescription(),
  childFile.getSize()/1024,
  childFile.getOwner().getEmail(),
];

至:

var ownerOfFile = childFile.getOwner();
data = [ 
  parentName + "/" + childFolder.getName() + "/" + childFile.getName(),
  childFile.getName(),
  "Files",
  childFile.getDateCreated(),
  childFile.getUrl(),
  childFile.getLastUpdated(),
  childFile.getDescription(),
  childFile.getSize()/1024,
  ownerOfFile ? ownerOfFile.getEmail() : "",
];

笔记:

  • 当我测试您的脚本反映了对共享云端硬盘的上述修改时,我可以确认该脚本有效。

【讨论】:

    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多