如何复制Google Sheet表格且副本不携带绑定的AppScript脚本
问题描述
在绑定于Google Sheets文件的Apps Script项目中开发时,需要将表格连同存储的全量数据复制到指定文件夹,原有实现脚本如下:
var CopyOfSheet = SpreadsheetApp.openById(Thischit).copy(Name.of.the.sheet).getId(); var SpecificFolder = DriveApp.getFolderById(ExlID); var File = DriveApp.getFileById(CopyOfSheet); SpecificFolder.addFile(File); File.getParents().next().removeFile(File);
上述脚本无论手动执行还是触发器触发,都能在目标文件夹成功生成表格副本,但复制逻辑会同步拷贝原文件绑定的Apps Script代码,需要实现副本不携带绑定脚本的复制效果,且执行复制操作的脚本本身存放在待复制的原Google Sheet文件中。
原因说明
你当前使用的SpreadsheetApp.copy()是容器文件完整克隆接口,绑定在Google Sheet上的Apps Script项目属于文件的附属组成部分,会随文件复制流程一同被拷贝,因此无法通过该接口直接生成无绑定脚本的副本。
可行实现方案
方案1:新建空白表格后批量复制工作表(推荐,无额外权限要求)
直接在目标位置创建全新的空白Google Sheet文件(默认无任何绑定脚本),再将原表的所有工作表逐个复制到新文件中,即可保留全部数据、格式、公式、条件格式、数据验证规则,且完全不会携带原文件的绑定脚本。
优化后的代码如下:
// 复用原有变量定义 const SOURCE_FILE_ID = Thischit; const TARGET_FOLDER_ID = ExlID; const COPY_FILE_NAME = Name.of.the.sheet; function copySheetWithoutBoundScript() { const sourceSs = SpreadsheetApp.openById(SOURCE_FILE_ID); const targetFolder = DriveApp.getFolderById(TARGET_FOLDER_ID); // 创建全新空白表格,默认无绑定脚本 const targetSs = SpreadsheetApp.create(COPY_FILE_NAME); // 删除空白表默认生成的初始工作表 targetSs.deleteSheet(targetSs.getSheets()[0]); // 遍历原表所有工作表复制到新表 sourceSs.getSheets().forEach(sheet => { sheet.copyTo(targetSs).setName(sheet.getName()); }); // 将新生成的表格移动到目标文件夹,替代旧版addFile+removeFile的写法 const targetFile = DriveApp.getFileById(targetSs.getId()); targetFile.moveTo(targetFolder); }
该方案不需要开启额外高级服务,兼容性最好,不会出现权限问题。
方案2:复制原文件后删除副本绑定的脚本项目
如果需要保留原表的命名范围、已安装触发器等高级配置,可以先复制完整文件,再调用Drive高级服务删除副本附带的绑定脚本。使用前需要先在Apps Script编辑器左侧「服务」栏添加Drive API(选择v2版本即可)。
示例代码:
const SOURCE_FILE_ID = Thischit; const TARGET_FOLDER_ID = ExlID; const COPY_FILE_NAME = Name.of.the.sheet; function copyAndRemoveScript() { const sourceFile = DriveApp.getFileById(SOURCE_FILE_ID); const targetFolder = DriveApp.getFolderById(TARGET_FOLDER_ID); // 直接在目标文件夹生成原文件副本 const copiedFile = sourceFile.makeCopy(COPY_FILE_NAME, targetFolder); // 获取副本绑定的脚本项目ID const fileMeta = Drive.Files.get(copiedFile.getId()); const boundScriptId = fileMeta.scriptId; // 删除绑定的脚本项目,trash是移到回收站,remove是彻底删除(不可逆) if (boundScriptId) { Drive.Files.trash(boundScriptId); } }
该方案需要账号对生成的副本绑定脚本有删除权限,由于副本所有者和执行脚本的账号一致,正常场景下权限满足要求。
内容的提问来源于stack exchange,提问作者ulises alvarez
相关产品推荐
相关产品推荐

