使用Google Apps Script覆盖PDF文件时Drive无法找到文件的问题
问题描述
我有一段Google Apps Script代码,用来把Google表格保存为PDF。需求是表格内容变更时直接更新现有PDF文件,而非新建文件后删除旧文件。理论上代码逻辑没问题,但调用高级Drive服务API时总是提示找不到文件——我确认File ID正确,且在其他场景(比如获取文件名)中Drive能正常找到该文件。
初始代码:
function replaceFile(theBlob, theFileId) { var oldFile = DriveApp.getFileById(theFileId); Logger.log(oldFile.getId()); try { Drive.Files.update( { title: oldFile.getName(), mimeType: oldFile.getMimeType() }, theFileId, theBlob, { convert: true, supportAllDrives: true } ); Logger.log("Success!"); SpreadsheetApp.getActive().toast("PDF Updated With Success"); } catch (error) { Logger.log(error); SpreadsheetApp.getActive().toast(error); } } function test1 () { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var pdfBlob = spreadsheet.getAs('application/pdf'); replaceFile(pdfBlob,"1UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc"); }
报错信息:
GoogleJsonResponseException: API call to drive.files.get failed with error: File not found: 11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc.
之后我更新了脚本,现在Drive.Files.get()能获取到文件,但Drive.Files.update()仍提示文件不存在。更新后的代码:
function replaceFile(theBlob, theFileId) { var oldFile = DriveApp.getFileById(theFileId); Logger.log(oldFile.getId()); try { Drive.Files.update( { mimeType: oldFile.getMimeType() }, theFileId, theBlob, { supportAllDrives: true } ); Logger.log(Drive.Files.get(theFileId, {supportsAllDrives: true}).getName()); Logger.log("Success!"); SpreadsheetApp.getActive().toast("PDF Updated With Success"); } catch (error) { Logger.log(error); SpreadsheetApp.getActive().toast(error); } } function test1 () { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); SpreadsheetApp.flush(); var pdfBlob = spreadsheet.getAs('application/pdf'); replaceFile(pdfBlob,"1ZuftxjH8t6WVKR-sxHl98iywhRPDHnC-"); }
解决方案
核心问题分析
问题出在高级Drive服务Files.update方法的参数配置不匹配,尤其是文件位于共享驱动器时,参数顺序和选项的细微偏差都会导致API报错。另外你之前的报错里File ID多了一个前缀1,大概率是复制时的手误,也要注意排查。
修正后的代码
function replaceFile(theBlob, theFileId) { const oldFile = DriveApp.getFileById(theFileId); Logger.log(oldFile.getId()); try { Drive.Files.update( {}, // 无需修改元数据时传空对象即可,避免冗余参数冲突 theFileId, theBlob, { supportsAllDrives: true, convert: false // Blob已经是PDF格式,无需转换 } ); Logger.log(Drive.Files.get(theFileId, {supportsAllDrives: true}).getName()); Logger.log("Success!"); SpreadsheetApp.getActive().toast("PDF更新成功"); } catch (error) { Logger.log(error); SpreadsheetApp.getActive().toast(error.message); } } function test1() { const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); SpreadsheetApp.flush(); // 确保表格所有变更已保存 const pdfBlob = spreadsheet.getAs('application/pdf'); replaceFile(pdfBlob, "1ZuftxjH8t6WVKR-sxHl98iywhRPDHnC-"); }
关键修正点
- 简化元数据参数:如果不需要修改文件名或MIME类型,直接传空对象
{},避免不必要的参数干扰API逻辑。 - 调整
convert参数:你传入的Blob已经是PDF格式,设置convert: false——如果设为true,Drive API会尝试强制转换格式,反而触发错误。 - 确认高级Drive服务版本:确保启用的是Drive API v3(默认是v2),v3版本中
supportsAllDrives是访问共享驱动器文件的必填参数。
额外检查项
- 确认高级Drive服务已启用:在脚本编辑器中点击「服务」→ 添加服务 → 选择「Drive API」并添加。
- 验证文件权限:确保脚本运行账号对目标PDF文件拥有编辑权限(仅查看权限无法更新)。
- 核对File ID:仔细检查传入的ID和报错信息中的ID是否一致,避免复制时的字符多输/漏输。
内容的提问来源于stack exchange,提问作者Nate Bohn
相关产品推荐
相关产品推荐

