同文件不同Sheet的Google Apps Script转PDF函数报错求助
问题描述
有一段可正常运行的Google Apps Script代码createBulkPDFs,能将Google Sheets中「PDF - translation」工作表的数据转为PDF。复制该代码并修改函数名与字段后,创建新脚本用于处理同文件的另一工作表时,始终报错TypeError: docFile.makeCopy is not a function。已尝试更换目标文档、临时文件夹及PDF文件夹,问题仍未解决。
正常运行的代码如下:
function createBulkPDFs() { const docFile = DriveApp.getFileById("1jcRQ3MWZFLZFJ3sgpXEC-CQ6kdhScREuxzK3YnTGidw"); const tempFolder = DriveApp.getFolderById("1GOKpDc32CrLIAqGnZimZu9LYynu8rhrn"); const pdfFolder = DriveApp.getFolderById("1iau3rHSDqiPLlf1g9VZP1ckEAt0tmuH2") const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PDF - translation"); const data = currentSheet.getRange(2,1,currentSheet.getLastRow()-1,21) .getValues(); data.forEach(row => { createPDF(row[0],row[12],row[13],row[14],row[15],row[16],row[17],row[18],row[19],row[2],row[3],row[4],row[20],docFile,tempFolder,pdfFolder) }) } function createPDF(jobnumber,startDate,startMonth,startYear,startHour,startMinute,endDate,endMonth,endYear,location,customer,reference,pdfName,docFile,tempFolder,pdfFolder) { const tempFile = docFile.makeCopy(tempFolder); const tempDocFile = DocumentApp.openById(tempFile.getId()); const body = tempDocFile.getBody(); body.replaceText("{jobnumber}", jobnumber); body.replaceText("{startdate}", startDate); body.replaceText("{startmonth}", startMonth); body.replaceText("{startyear}", startYear); body.replaceText("{starthour}", startHour); body.replaceText("{startminute}", startMinute); body.replaceText("{enddate}", endDate); body.replaceText("{endmonth}", endMonth); body.replaceText("{endyear}", endYear); body.replaceText("{location}", location); body.replaceText("{customer}", customer); body.replaceText("{reference}", reference); tempDocFile.saveAndClose(); const pdfContentBlob = tempFile.getAs(MimeType.PDF); pdfFolder.createFile(pdfContentBlob).setName(pdfName); tempFolder.removeFile(tempFile); DriveApp.getFileById(tempFile.getId()).setTrashed(true); }
报错原因分析
makeCopy()是Google Drive中File对象专属方法,报错说明你的docFile变量并非有效的File对象,常见原因包括:
- 新脚本中填写的文档ID错误,或ID对应的不是Google Docs文档(比如是Google Sheets、文件夹或已删除的文件)
- 脚本运行账号没有访问目标文档的权限
- 修改代码时调整了
createPDF函数的参数顺序,导致传递给docFile的不是File对象(比如误传了文件夹或表格数据) - 笔误将
DriveApp.getFileById()写成了DriveApp.getFolderById(),得到的Folder对象没有makeCopy方法
排查与解决步骤
核对文档ID有效性
确认新脚本中DriveApp.getFileById("XXX")的ID对应真实存在的Google Docs文档:直接在浏览器中打开https://docs.google.com/document/d/XXX/edit,检查是否能正常访问该文档,且文档类型为Google Docs(不是表格或文件夹)。测试文件获取权限
在脚本编辑器中新建测试函数,验证能否正常获取目标文件:function testDocAccess() { const testDocId = "你的新文档ID"; try { const file = DriveApp.getFileById(testDocId); console.log("文档名称:" + file.getName()); } catch(e) { console.log("错误信息:" + e.message); } }运行后查看日志(编辑器右上角「查看」→「日志」),如果报错,说明ID无效或无权限,需修正ID或给脚本运行账号添加文档访问权限。
检查参数传递顺序
对比新脚本中createPDF函数的定义和调用代码,确保docFile、tempFolder、pdfFolder的传递位置完全一致。比如原代码中createPDF的最后三个参数是docFile,tempFolder,pdfFolder,修改后若调整了参数顺序,会导致传错对象。排查代码笔误
仔细检查新脚本中docFile的赋值语句,确认是DriveApp.getFileById()而非DriveApp.getFolderById(),后者返回的是文件夹对象,不支持makeCopy方法。
修改后的示例代码
function createBulkPDFsNew() { // 替换为新目标文档的ID const docFile = DriveApp.getFileById("你的新文档ID"); const tempFolder = DriveApp.getFolderById("1GOKpDc32CrLIAqGnZimZu9LYynu8rhrn"); const pdfFolder = DriveApp.getFolderById("1iau3rHSDqiPLlf1g9VZP1ckEAt0tmuH2"); // 替换为目标工作表名称 const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("你的新工作表名称"); const data = currentSheet.getRange(2,1,currentSheet.getLastRow()-1,21).getValues(); data.forEach(row => { // 确保参数顺序与createPDFNew定义一致 createPDFNew(row[0],row[12],row[13],row[14],row[15],row[16],row[17],row[18],row[19],row[2],row[3],row[4],row[20],docFile,tempFolder,pdfFolder) }); } function createPDFNew(jobnumber,startDate,startMonth,startYear,startHour,startMinute,endDate,endMonth,endYear,location,customer,reference,pdfName,docFile,tempFolder,pdfFolder) { const tempFile = docFile.makeCopy(tempFolder); const tempDocFile = DocumentApp.openById(tempFile.getId()); const body = tempDocFile.getBody(); // 根据新文档的占位符调整替换内容 body.replaceText("{jobnumber}", jobnumber); body.replaceText("{startdate}", startDate); // ... 其他替换字段按需修改 tempDocFile.saveAndClose(); const pdfContentBlob = tempFile.getAs(MimeType.PDF); pdfFolder.createFile(pdfContentBlob).setName(pdfName); tempFolder.removeFile(tempFile); DriveApp.getFileById(tempFile.getId()).setTrashed(true); }
内容的提问来源于stack exchange,提问作者Tramy Le

