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

Google Sheets转PDF存Drive脚本共享后报访问拒绝错误

问题描述
  • 使用本人Gmail账号运行绑定Google表格的脚本时,功能可正常执行
  • 将关联脚本的Google表格共享给其他Gmail账号后,脚本运行持续报错
  • 报错信息:Exception: Access denied: DriveApp.

现有脚本实现逻辑:将指定工作表导出为PDF格式,保存至个人Google Drive指定文件夹,同时将PDF作为附件发送给指定联系人。
目标需求:其他用户获得工作表使用权限时,代码可正常运行,解决上述权限报错。

原始代码
function sendReport(range) {
  SpreadsheetApp.getActive().getSheetByName("Customers").hideSheet();
    SpreadsheetApp.getActive().getSheetByName("Products").hideSheet();
      SpreadsheetApp.getActive().getSheetByName("SO Log").hideSheet();
        SpreadsheetApp.getActive().getSheetByName("SOF").hideSheet();

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var SOSheet = ss.getSheetByName("Sales Order");
  var name = SOSheet.getRange('F10').getValue();
  

  var message = {
    to: "random@gmail.com",
    subject: "Sales Order",
    body: "Hi team,\n\nPlease find the Sales Order attached.\n\nThank you",
    name: "Dave",
    attachments: [SpreadsheetApp.getActiveSpreadsheet().getAs(MimeType.PDF).setName("SO"+name)]
  }
  MailApp.sendEmail(message);

  SpreadsheetApp.getActive().getSheetByName("Customers").showSheet();
  SpreadsheetApp.getActive().getSheetByName("Products").showSheet();
  SpreadsheetApp.getActive().getSheetByName("SO Log").showSheet();
  SpreadsheetApp.getActive().getSheetByName("SOF").showSheet();
  

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var token = ScriptApp.getOAuthToken();
  var sheet = ss.getSheetByName("Sales Order");
  var bogus = DriveApp.getRootFolder();


  //Creating an exportable URL
  var url = "https://docs.google.com/spreadsheets/d/SS_ID/exSOrt?".replace("SS_ID", ss.getId());
  var folderID = "1KU7ylGsci9qsVzxU2ZlCW"; // Folder id to save in a folder.
  var folder = DriveApp.getFolderById(folderID);
  var SOcode = ss.getRange("'Sales Order'!F10").getValue()
  var pdfName = "SO" + SOcode;
  

  /* Specify PDF export parameters
  */
  var url_ext = 'exportFormat=pdf&format=pdf'        // export as pdf / csv / xls / xlsx
  + '&size=A4'                       // paper size legal / letter / A4
  + '&SOrtrait=true'                    // orientation, false for landscape
  + '&fitw=true&source=labnol'           // fit to page width, false for actual size
  + '&sheetnames=false&printtitle=false' // hide optional headers and footers
  + '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
  + '&fzr=false'                         // do not repeat row headers (frozen rows) on each page
  + '&gid=';                             // the sheet's Id
    
  // Convert individual worksheet to PDF

  var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
    headers: {
      'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},muteHttpExceptions:true});
    
    
  
  ;
  

var blobs = response.getBlob().setName(pdfName + '.pdf');


var folders = folder.getFoldersByName(pdfName);
folder = folders.hasNext() ? folders.next() : folder.createFolder(pdfName);


var newFile = folder.createFile(blobs);
var newFileLink = newFile.getUrl();
var SOcode = ss.getRange("'SOF'!F12").getValue();
var writePDFLink =  ss.getRange("'SOF'!L1").setValue(newFileLink);

  
  // Define the scope
  Logger.log("Storage Space used: " + DriveApp.getStorageUsed());

}
报错原因
  • 脚本默认以当前触发操作的用户身份运行,权限和当前用户完全对齐
  • 代码中硬编码的目标Drive文件夹属于你个人账号,其他被共享表格的用户默认没有该文件夹的编辑/写入权限,调用DriveApp.getFolderById访问该文件夹时会直接触发权限拒绝
  • 代码本身存在3处会导致功能异常的笔误:导出URL路径中exSOrt拼写错误、PDF参数中SOrtrait拼写错误、URL参数连接符错误使用HTML转义字符&而非实际需要的&
解决方案

根据使用场景二选一即可:

方案1:调整文件夹权限(改动最小,适合使用人数少的场景)

  1. 打开个人Google Drive中ID为1KU7ylGsci9qsVzxU2ZlCW的目标文件夹
  2. 将该文件夹共享给所有需要运行脚本的用户,授予编辑者权限
  3. 修正代码中的笔误:
    • 将URL中的exSOrt替换为export
    • 将参数中的&SOrtrait=true替换为&portrait=true
    • 将所有&替换为&
  4. 保存脚本后重新授权即可正常运行

注意:该方案下邮件会以当前运行脚本的用户身份发送,如需固定发件人为本人,请选择方案2。

方案2:部署为所有者权限运行的Web应用(无需开放个人文件夹权限,适合多用户使用场景)

  1. 打开脚本编辑器,点击左侧「项目设置」,勾选「在编辑器中显示"appsscript.json"清单文件」
  2. 回到编辑器页面,打开左侧文件列表中的appsscript.json,补充所需权限声明,完整内容如下:
{
  "timeZone": "Asia/Shanghai",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/script.send_mail"
  ]
}
  1. 按方案1中的说明修正代码里的3处笔误
  2. 点击编辑器右上角「部署」→「新建部署」,部署类型选择「Web应用」
  3. 「执行身份」选择我(你的邮箱账号),「访问权限」选择「任何拥有Google账号的人」,点击完成部署,复制生成的Web应用URL
  4. 将表格内原来绑定sendReport函数的按钮,改为绑定调用Web应用的触发函数即可,示例触发函数:
function triggerSendReport() {
  UrlFetchApp.fetch("你复制的Web应用URL", {
    method: "post",
    headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}
  })
}

该方案下无论哪个用户触发操作,脚本始终以你的身份运行,天然拥有个人Drive文件夹的访问权限,不需要给其他用户开放文件夹权限,同时邮件发件人也固定为你的账号。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:30:52