如何用Google Apps Script更新Google Docs中嵌入的图表
解决Google Docs嵌入Sheet图表无法自动更新的问题
问题背景
首次使用Google Apps Script实现从Google Sheets自动生成Google Docs报告并导出PDF,已完成文本随Sheet数据自动替换、PDF生成,但嵌入Docs的5个Sheet图表无法同步Sheet中的数据更新——Sheet图表随数据变化,但Docs里的图表只能手动点击刷新,尝试重新生成图表等方案均无效。输入数据为20-80的数字,对应图表中等Y值的点,其余4个图表逻辑类似。
原代码如下:
const sheetID = '--[Sheet ID, blanked out for security reasons]--'; const docID = '--[Docs ID, blanked out for security reasons]--'; const folderID = '--[Folder location, blanked out for security reasons]--'; function genRapport() { const sheet = SpreadsheetApp.openById(sheetID).getSheetByName('Score summary'); const temp = DriveApp.getFileById(docID); const folder = DriveApp.getFolderById(folderID); const pID = sheet.getRange('B1').getValue(); //Cell for ID var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy") const file = temp.makeCopy(folder).setName(pID ); const doc = DocumentApp.openById(file.getId()); const body = doc.getBody(); body.replaceText('{{pID}}', pID ); body.replaceText('{{date}}', date); body.replaceText('{{E score}}', sheet.getRange('AZ4').getValue()); // Replaces {E score} with actual score from spreadsheet. body.updateChart(); // <- this is where the issue is. doc.saveAndClose(); const pdf = folder.createFile(doc.getAs(MimeType.PDF)).setName(pID+'.pdf'); // Generates PDF //file.setTrashed(true) //Deletes Docs-file }
解决方案
原代码中body.updateChart()是错误用法,DocumentApp的Body类没有该方法。需要遍历文档中所有内嵌的链接图表,逐个调用刷新方法,同时给刷新留足够时间再生成PDF。
修改后的代码:
const sheetID = '--[Sheet ID, blanked out for security reasons]--'; const docID = '--[Docs ID, blanked out for security reasons]--'; const folderID = '--[Folder location, blanked out for security reasons]--'; function genRapport() { const sheet = SpreadsheetApp.openById(sheetID).getSheetByName('Score summary'); const temp = DriveApp.getFileById(docID); const folder = DriveApp.getFolderById(folderID); const pID = sheet.getRange('B1').getValue(); const date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy"); // 复制模板文档 const file = temp.makeCopy(folder).setName(pID); const doc = DocumentApp.openById(file.getId()); const body = doc.getBody(); // 替换文本内容 body.replaceText('{{pID}}', pID); body.replaceText('{{date}}', date); body.replaceText('{{E score}}', sheet.getRange('AZ4').getValue()); // 刷新所有内嵌的Sheet链接图表 const images = body.getImages(); for (let image of images) { const chart = image.getLinkedChart(); if (chart) { chart.refresh(); // 强制从源Sheet同步最新数据 } } // 等待图表刷新完成(根据图表数量调整延迟时间) Utilities.sleep(3000); doc.saveAndClose(); // 生成PDF并命名 const pdf = folder.createFile(doc.getAs(MimeType.PDF)).setName(`${pID}.pdf`); // 删除临时Docs文件(取消注释启用) // file.setTrashed(true); }
关键说明
- 遍历内嵌图表:通过
body.getImages()获取文档中所有内嵌对象,再用getLinkedChart()筛选出链接到Sheet的图表 - 强制刷新:对每个链接图表调用
refresh()方法,触发从源Sheet拉取最新数据 - 延迟等待:图表刷新需要一定时间,添加
Utilities.sleep(3000)(3秒)确保刷新完成后再生成PDF,避免PDF中还是旧图表。如果图表较多或数据量大,可适当延长延迟时间
内容的提问来源于stack exchange,提问作者ripsraps
相关产品推荐
相关产品推荐

