Google Apps Script 将电子表格每列存为独立文件的问题求解
问题核心原因
你的推测完全正确,Google Apps Script为了提升运行性能,对电子表格的修改默认会暂存在内存中,批量同步到云端存储,因此循环中调用makeCopy()时,你刚写入的内容还没同步到云端的模板文件,复制出的所有文件都是模板初始状态。
另外你提到的「打开新文件需要单独授权」是误解:Apps Script的授权是项目级的,你首次运行脚本时授予对应权限后,后续循环中打开新生成的文件不需要重复点击确认,可放心批量处理300列规模的需求。
可行解决方案
方案1:最小改动修复现有逻辑
仅需在写入数据后、复制文件前加一行SpreadsheetApp.flush(),这个方法会强制将内存中所有未同步的修改立即写入云端模板文件,后续复制的就是包含当前列数据的版本。
修改后的核心循环代码如下:
for(var i = 2; i <= x; i ++) { var data = source.getRange(1,i,y,1).getValues(); // 写入数据到模板 target.getRange(1,2,y,1).setValues(data); // 强制同步内存修改到云端 SpreadsheetApp.flush(); // 复制包含当前数据的模板 DestinationFilename = source.getRange(1,i,1,1).getValue(); DriveApp.getFileById(dss.getId()).makeCopy(DestinationFilename, destFolder); };
注意这个方案会修改你当前打开的模板文件内容,循环结束后模板会保留最后一列的数据。
方案2:不修改原模板的更稳定实现
如果不想改动原模板文件,可以调整逻辑:先复制模板生成新文件,再直接往新文件写入对应列数据,代码示例如下:
function myFunction5() { /** x - Number of columns */ let x = 8 /** y - Number of rows */ let y = 8 /** Destination Folder ID, where the generated files will be saved. */ var destFolder = DriveApp.getFolderById("Destination_Folder_ID"); /** Source spreadsheet file ID */ var ss = SpreadsheetApp.openById("Source_Spreadsheet_ID"); var source = ss.getSheetByName("sheet1"); // 填入模板文件ID,全程不会修改原模板内容 var templateFile = DriveApp.getFileById("Template_Spreadsheet_ID"); for(var i = 2; i <= x; i ++) { var data = source.getRange(1,i,y,1).getValues(); var DestinationFilename = source.getRange(1,i,1,1).getValue(); // 先复制模板得到新文件 var newFile = templateFile.makeCopy(DestinationFilename, destFolder); // 打开新文件写入数据,无需重复授权 var newSs = SpreadsheetApp.openById(newFile.getId()); var newTarget = newSs.getSheetByName("sheet1"); newTarget.getRange(1,2,y,1).setValues(data); }; }
内容的提问来源于stack exchange,提问作者Bojan Mrkobrad
相关产品推荐
相关产品推荐

