无需授予编辑权限,让其他用户从Google Sheets传文件至Google Drive
无需授予文件夹编辑权限实现文件上传的解决方案
核心问题在于当前脚本通过google.script.run执行服务器端函数时,会使用当前操作表格的用户权限,因此其他用户需要拥有目标Drive文件夹的编辑权限才能上传。要解决这个问题,我们需要让文件创建操作使用表格/文件夹所有者的权限,而非操作用户的权限。以下是两种可行方案:
方案一:部署为以所有者身份运行的Web App(推荐)
将脚本部署为Web App,设置其以你(所有者)的身份运行。此时用户上传的文件数据会发送到Web App,由Web App使用你的权限完成文件创建,无需其他用户拥有文件夹访问权限。
步骤及代码修改:
- 修改服务器端脚本
添加doPost函数处理来自对话框的上传请求,保留openAttachmentDialog函数不变:
function openAttachmentDialog() { var html = HtmlService.createHtmlOutputFromFile('UploadFile'); SpreadsheetApp.getUi().showModalDialog(html, 'Upload File'); } // 处理Web App的POST请求 function doPost(e) { try { var obj = JSON.parse(e.postData.contents); var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName); var file = DriveApp.getFolderById("18bws1zMXcvTrur9Y30QisZQzXuRqTrWd").createFile(blob); var cellFormula = file.getUrl(); // 替换为你的工作表名称,确保evcssheet变量可访问 var evcssheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1"); evcssheet.getRange('F1').setValue(cellFormula); return ContentService.createTextOutput(JSON.stringify({id: file.getId()})).setMimeType(ContentService.MimeType.JSON); } catch (error) { return ContentService.createTextOutput(JSON.stringify({error: error.message})).setMimeType(ContentService.MimeType.JSON); } }
部署Web App
- 点击菜单栏的「发布」→「部署为Web应用」
- 「执行方式」选择我(你的邮箱地址)
- 「谁可以访问此应用」选择任何人,甚至匿名(或根据需求选择「您的网域内的任何人」)
- 点击部署,复制生成的Web App URL
修改客户端HTML代码
将原有的google.script.run调用替换为向Web App发送请求的代码:
<!DOCTYPE html> <html> <head> <base target="_top"> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> </head> <script> // 替换为你部署的Web App URL const WEB_APP_URL = "https://script.google.com/macros/s/[你的Web App ID]/exec"; function getFiles() { document.getElementById("uploadButton").disabled = true; const progressText = document.getElementById("progress"); const f = document.getElementById('files'); var uploadCompletedCount = 0; progressText.innerHTML = "正在上传文件 " + (uploadCompletedCount + 1) + "/" + [...f.files].length; [...f.files].forEach((file, i) => { const fr = new FileReader(); fr.onload = (e) => { const data = e.target.result.split(","); const obj = { fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1] }; // 向Web App发送上传请求 fetch(WEB_APP_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(obj) }) .then(response => response.json()) .then(result => { if (result.error) { progressText.innerHTML = "上传失败:" + result.error; return; } uploadCompletedCount++; progressText.innerHTML = "上传完成"; if (uploadCompletedCount >= [...f.files].length){ google.script.host.close(); } else { progressText.innerHTML = "正在上传文件 " + (uploadCompletedCount + 1) + "/" + [...f.files].length; } }) .catch(error => { progressText.innerHTML = "上传失败:" + error.message; }); }; fr.readAsDataURL(file); }); } </script> <body> <input type="file" name="upload" id="files"/> <input type='button' id="uploadButton" value='上传' onclick='getFiles()' class="action"> <br><br> <div id="progress"> </div> </body> </html>
方案一注意事项:
- 替换代码中的
[你的Web App ID]为部署Web App时生成的实际ID - 确保
evcssheet变量指向正确的工作表(原代码中未定义该变量,需根据实际情况调整) - 部署Web App时需要授权你的Google账号,授予必要的Drive访问权限
方案二:使用服务账号(进阶)
如果需要更高的控制权,可使用Google Cloud服务账号实现上传:
- 在Google Cloud控制台创建服务账号
- 将目标Drive文件夹共享给服务账号邮箱(授予编辑权限)
- 在脚本中使用Drive API通过服务账号认证并上传文件
此方案需启用Drive API,配置相对复杂,适合有开发经验的用户。
核心原理说明
方案一中,Web App以所有者身份运行,因此doPost函数使用所有者的Drive权限创建文件,其他用户仅需将文件数据发送至Web App,无需直接访问目标文件夹,从而避免了授予文件夹编辑权限的需求。
内容的提问来源于stack exchange,提问作者Rajeeb Roy
相关产品推荐
相关产品推荐

