如何通过GAS强制更新Google Slides并生成最新PDF?
问题解决:链式调用GAS脚本时幻灯片更新未同步到PDF
问题原因
Google Apps Script中,SlidesApp对幻灯片的修改默认会延迟到脚本执行结束后才同步到云端。当你通过CHAIN()连续调用EditPDF()和EmailPDF()时,EditPDF的本地修改还未同步到云端,EmailPDF通过UrlFetch拉取的是旧版本幻灯片,导致PDF无更新。
方法1:手动强制同步幻灯片修改(推荐)
在EditPDF()函数末尾添加Template.saveAndClose(),强制将本地修改同步到云端,确保EmailPDF()拉取的是最新版本。
修改后的EditPDF()代码:
function EditPDF () { Logger.log("Editing!"); var Sapp = SpreadsheetApp; var Papp = SlidesApp; var FS = Sapp.getActiveSpreadsheet().getSheetByName("Form Submissions"); var Template = Papp.openById("10Up_PcLxVopXont9Qcu-yk-PrFGWfWPQ3ETsgys4v0Y") var TSlide = Template.getSlideById("g2580bcdba17_0_22"); var TBox = TSlide.getShapes(); var Prod1 = FS.getRange("B"+FS.getLastRow()).getValue(); var Farm1 = FS.getRange("C"+FS.getLastRow()).getValue(); var Loc1 = FS.getRange("D"+FS.getLastRow()).getValue(); var Price1 = FS.getRange("E"+FS.getLastRow()).getValue(); var Prod2 = FS.getRange("F"+FS.getLastRow()).getValue(); var Farm2 = FS.getRange("G"+FS.getLastRow()).getValue(); var Loc2 = FS.getRange("H"+FS.getLastRow()).getValue(); var Price2 = FS.getRange("I"+FS.getLastRow()).getValue(); var Prod3 = FS.getRange("J"+FS.getLastRow()).getValue(); var Farm3 = FS.getRange("K"+FS.getLastRow()).getValue(); var Loc3 = FS.getRange("L"+FS.getLastRow()).getValue(); var Price3 = FS.getRange("M"+FS.getLastRow()).getValue(); TBox[0].getText().setText(Prod1); TBox[1].getText().setText(Farm1); TBox[2].getText().setText(Loc1); TBox[3].getText().setText(Price1); TBox[4].getText().setText(Prod2); TBox[5].getText().setText(Farm2); TBox[6].getText().setText(Loc2); TBox[7].getText().setText(Price2); TBox[8].getText().setText(Prod3); TBox[9].getText().setText(Farm3); TBox[10].getText().setText(Loc3); TBox[11].getText().setText(Price3); // 强制保存并关闭模板,同步修改到云端 Template.saveAndClose(); }
简化后的EmailPDF()代码(移除重复打开模板的冗余逻辑):
function EmailPDF () { Logger.log("Emailing!"); var Sapp = SpreadsheetApp; var FS = Sapp.getActiveSpreadsheet().getSheetByName("Form Submissions"); var ssID = "10Up_PcLxVopXont9Qcu-yk-PrFGWfWPQ3ETsgys4v0Y"; var Addy1 = FS.getRange("N"+FS.getLastRow()).getValue(); var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}}; var url = "https://docs.google.com/presentation/d/"+ ssID + "/export?format=pdf&id="+ssID; var result = UrlFetchApp.fetch(url , requestData); var contents = result.getContent(); MailApp.sendEmail(Addy1,"Local Sign Template" ,"Here is your custom sign Template.", {attachments:[{fileName: "LST.pdf", content:contents, mimeType:"application/pdf"}]}); }
方法2:分阶段触发器执行
若不想手动保存,可通过触发器拆分执行流程:
- 删除
CHAIN()函数,为EditPDF()设置表单提交触发器,确保表单数据提交后立即执行修改。 - 为
EmailPDF()设置时间驱动触发器(延迟1分钟执行),等待EditPDF()的修改同步到云端后再生成PDF并发送邮件。
注意:这种方法需确保每次执行只处理最新的表单提交行,避免多提交场景下的数据混淆。
额外说明
- 无需使用Batch Update,你的场景中直接修改文本框已满足需求,手动保存是最直接的同步方案。
Utilities.sleep()无效是因为它仅延迟脚本执行,不会触发本地修改到云端的同步。
内容的提问来源于stack exchange,提问作者Noah Galvin
相关产品推荐
相关产品推荐

