You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改Google Sheets脚本实现Google Drive批量创建多个子文件夹

Google Sheets 批量创建多子文件夹脚本修改方案

前置说明

原脚本仅支持每个父文件夹下创建1个子文件夹,调整后可支持自定义数量子文件夹批量创建。

具体修改步骤

  • 调整表格结构
    原表格C列为子文件夹名,现在将C列及后续多列设为子文件夹名列,可根据需要的子文件夹数量新增对应列,原许可邮箱列、文件夹链接列依次后移,调整完成后同步修改Config页面对应的列序号配置即可。
  • 替换原有脚本代码,修改后的完整可运行代码如下:
// 注意:原脚本开头的getSpreadsheetData函数可保持不变,核心功能修改代码如下

/*
该函数遍历每一行数据,触发Google Drive文件夹及子文件夹创建
如果配置了权限则自动添加对应权限
*/
function createFolders(spreadsheetData) {
  // 从键值对数组提取数据
  var ss = spreadsheetData['ss'];
  var timeZone = spreadsheetData['timeZone'];
  var dataSheet = spreadsheetData['dataSheet'];
  var destinationFolderId = spreadsheetData['destinationFolderId'];
  var permissionFlag = spreadsheetData['permissionFlag'];
  var folderLinkCol = spreadsheetData['folderLinkCol'];
  var permAddedCol = spreadsheetData['permAddedCol'];
  // 子文件夹列结束索引:根据实际表格调整,比如子文件夹占C、D、E三列,对应数组索引2、3、4,结束索引就是4
  var subFolderEndColIndex = 4; 
  var data = spreadsheetData['data'];

  // 获取最后一行行号
  var lastRow = dataSheet.getLastRow();

  // 逐行遍历循环开始 ********************************
  for (var i = 1; i < lastRow; i++) {
    // 提取行内数据方便调用
    var folderNameP1 = data[i][0];
    Logger.log('父文件夹名称第一段: ' + folderNameP1);
    var folderNameP2 = data[i][1];
    Logger.log('父文件夹名称第二段: ' + folderNameP2);
    // 提取所有子文件夹名称,自动过滤空值
    var subFolderNames = data[i].slice(2, subFolderEndColIndex + 1).filter(name => name && name.trim() !== '');
    Logger.log('子文件夹名称列表: ' + subFolderNames);
    var permissionEmail = data[i][subFolderEndColIndex + 1];
    Logger.log('权限邮箱: ' + permissionEmail);
    var folderLink = data[i][subFolderEndColIndex + 2];
    Logger.log('文件夹链接: ' + folderLink);

    // 文件夹链接列为空才执行创建,避免重复创建
    if (folderLink == '') {
      // 拼接父文件夹完整名称
      var folderName = folderNameP1 + ' - ' + folderNameP2;
      Logger.log('父文件夹完整名称: ' + folderName);

      // 弹出Toast提示
      ss.toast(folderName, '正在创建文件夹');

      // 调用函数创建父文件夹和所有子文件夹
      var folderDetails = createFolder(folderName, destinationFolderId, subFolderNames);

      // 检查文件夹创建成功
      if (folderDetails) {
        // 提取URL和ID
        var newFolderUrl = folderDetails['newFolderUrl'];
        var newFolderId = folderDetails['newFolderId'];
        var subFolderIds = folderDetails['subFolderIds'];

        // 给文件夹链接列写入超链接公式
        var newFolderLink = '=HYPERLINK("' + newFolderUrl + '","' + folderName + '")';
        dataSheet.getRange(i + 1, folderLinkCol).setFormula(newFolderLink);

        // 检查是否需要添加权限,Config页面配置
        if (permissionFlag == 'Yes') {
          // 调用函数添加文件夹权限
          var currentRow = i + 1;
          var addPermissionsFlag = addPermissions(timeZone, dataSheet, permissionEmail,
            newFolderId, subFolderIds, currentRow, permAddedCol);

          // 权限添加失败则返回错误提示
          if (addPermissionsFlag == false) {
            ss.toast('文件夹' + folderName + '添加权限失败', '错误');
            return false;
          }
        }

        // 刷新表格实时更新每行执行结果
        SpreadsheetApp.flush();
      } else {
        // 文件夹创建失败写入错误提示
        dataSheet.getRange(i + 1, folderLinkCol).setValue('创建文件夹失败,请查看日志');
        return false;
      }
    }
  }// 逐行遍历循环结束 **********************************

  // 全部执行成功
  return true;
}

/*
创建Google Drive文件夹并返回URL、ID等信息
*/
function createFolder(folderName, destinationFolderId, subFolderNames) {
  try {
    // 获取目标存储文件夹
    var destinationFolder = DriveApp.getFolderById(destinationFolderId);
  } catch (e) {
    logEvent('获取目标存储文件夹错误: ' + e + e.stack);
    var destinationFolder = false;
  }

  // 成功获取目标文件夹才继续执行
  if (destinationFolder) {
    try {
      // 在目标文件夹下创建新的父文件夹
      var newFolder = destinationFolder.createFolder(folderName);
      var newFolderUrl = newFolder.getUrl();
      var newFolderId = newFolder.getId();
      var subFolderIds = [];
      // 循环创建所有子文件夹
      subFolderNames.forEach(name => {
        var subFolderId = newFolder.createFolder(name.trim()).getId();
        subFolderIds.push(subFolderId);
      });
      // 返回文件夹详情
      var folderDetails = { newFolderUrl: newFolderUrl, newFolderId: newFolderId, subFolderIds: subFolderIds };
      return folderDetails;
    } catch (e) {
      logEvent('创建文件夹错误: ' + e + e.stack);
      return false;
    }
  } else {
    return false;
  }
}

/*
给指定邮箱添加文件夹编辑权限
*/
function addPermissions(timeZone, dataSheet, permissionEmail, newFolderId, subFolderIds, currentRow, permAddedCol) {
  // 拆分多个邮箱地址为数组
  var emailAddresses = permissionEmail.split(', ');
  Logger.log('邮箱地址列表: ' + emailAddresses);
  var emailAddressesLength = emailAddresses.length;

  try {
    // 获取父文件夹对象
    var newFolder = DriveApp.getFolderById(newFolderId);
    // 获取所有子文件夹对象
    var subFolders = subFolderIds.map(id => DriveApp.getFolderById(id));
  } catch (e) {
    logEvent('获取文件夹错误: ' + e + e.stack);
    var newFolder = false;
  }

  if (newFolder && subFolders.length === subFolderIds.length) {
    // 遍历所有邮箱添加编辑权限 *******************
    for (var i = 0; i < emailAddressesLength; i++) {
      var emailAddress = emailAddresses[i].trim();
      Logger.log('待添加权限的邮箱: ' + emailAddress);
      try {
        // 给父文件夹加编辑权限
        newFolder.addEditor(emailAddress);
        // 给所有子文件夹加编辑权限
        subFolders.forEach(folder => folder.addEditor(emailAddress));
        var addEditor = true;
      } catch (e) {
        logEvent('添加编辑者错误: ' + e + e.stack);
        var addEditor = false;
      }

      if (addEditor) {
        // 写入权限添加时间戳
        var date = new Date;
        var timeStamp = Utilities.formatDate(date, timeZone, "yy/MM/dd HH:mm:ss");
        dataSheet.getRange(currentRow, permAddedCol).setValue(timeStamp);
      } else {
        dataSheet.getRange(currentRow, permAddedCol).setValue('添加编辑者失败,请查看日志');
        return false;
      }
    }
    // 邮箱遍历结束 *******************
  } else {
    dataSheet.getRange(currentRow, permAddedCol).setValue('获取文件夹失败,请查看日志');
    return false;
  }
  return true;
}

/*
日志输出函数,可在脚本任意位置调用写入日志页
*/
function logEvent(action) {
  // 获取当前运行脚本的用户邮箱
  var theUser = Session.getActiveUser().getEmail();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var logSheet = ss.getSheetByName('Log');
  // 生成格式化时间戳
  var dateTime = new Date();
  var timeZone = ss.getSpreadsheetTimeZone();
  var niceDateTime = Utilities.formatDate(dateTime, timeZone, "yy/MM/dd HH:mm:ss");
  // 组装日志数据
  var logData = [niceDateTime, theUser, action];
  // 追加到日志页最后一行
  logSheet.appendRow(logData);
}

/*
打开表格时自动创建自定义菜单
*/
function onOpen() {
  SpreadsheetApp.getUi()
  .createMenu('管理工具')
  .addItem('批量创建文件夹', 'getSpreadsheetData')
  .addToUi();
}
  • 调整代码内的subFolderEndColIndex参数,和实际表格的子文件夹列结束位置对应即可正常使用。

内容的提问来源于stack exchange,提问作者Mee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:15:04