Google Apps Script中Spreadsheet弹窗动态更新rowIndex变量问题
问题:Google Apps Script弹窗无法实时更新循环中的rowIndex值
在Google Apps Script的forEach循环中,需要让Spreadsheet弹窗实时显示并更新循环内的rowIndex变量,但当前弹窗仅显示最后一个rowIndex值,仅弹窗标题能动态变化,HTML内容始终只展示最终的rowIndex。
现有代码
HTML文件(html_file.html)
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <p align="center"> <?!=htmlVariable?> This is htmlVariable. </p> <p align="center"><button onclick="google.script.host.close()">Close</button></p> <script> function closer(){ google.script.host.close(); } </script> </body> </html>
Apps Script函数
function extractTestCases(ProgressUIInstance, _startTime) { const ui = SpreadsheetApp.getUi(); // .....Some Code...... let tempHtmlOutput = HtmlService.createTemplateFromFile('html_file'); tempHtmlOutput.htmlVariable = "Starting. . ." const dialog = ui.showModelessDialog(tempHtmlOutput.evaluate(), "Extractingg Test Cases"); // .....Some Code...... // 6. Processing Each Row values.forEach((row, rowIndex) => { // .....Some Code...... let dialogCount = 1; while ((match = regex.exec(testCaseText)) !== null) { // .....Some Code...... let endTime = new Date(); const elapsedSeconds = endTime - _startTime; Utilities.sleep(500); tempHtmlOutput.htmlVariable = rowIndex; ui.showModelessDialog(tempHtmlOutput.evaluate(), `EXTRACT - Row ${rowIndex + 1} - Dialog ${dialogCount}`); SpreadsheetApp.flush(); Utilities.sleep(500); dialogCount++; } // .....Some Code...... }); // .....Some Code...... }
当前输出
弹窗仅显示最后一个rowIndex值。
期望输出
弹窗中顺序显示以下内容:
0 This is html variable. 1 This is html variable. 2 This is html variable. 3 This is html variable. 4 This is html variable.
解决方案
问题根源在于每次循环都重新创建并显示新弹窗,且服务器端模板渲染是一次性的,无法实时更新已打开弹窗的内容。正确做法是保持单个弹窗打开,通过客户端脚本主动从服务器端获取最新状态。
1. 修改HTML文件,添加实时更新逻辑
<!DOCTYPE html> <html> <head> <base target="_top"> <script> // 页面加载后启动定时更新 window.onload = function() { updateProgress(); }; function updateProgress() { // 调用服务器端方法获取当前rowIndex google.script.run .withSuccessHandler(function(newIndex) { const progressText = document.getElementById('progress-text'); progressText.textContent = `${newIndex} This is html variable.`; // 未完成则继续定时更新 if (newIndex !== "Done") { setTimeout(updateProgress, 500); } }) .getCurrentRowIndex(); } function closer() { google.script.host.close(); } </script> </head> <body> <p align="center" id="progress-text">Starting. . . This is html variable.</p> <p align="center"><button onclick="closer()">Close</button></p> </body> </html>
2. 修改Apps Script函数,添加全局变量和状态获取方法
// 全局变量存储当前处理的rowIndex,供客户端调用 let currentRowIndex = "Starting. . ."; function extractTestCases(ProgressUIInstance, _startTime) { const ui = SpreadsheetApp.getUi(); // 重置状态为初始值 currentRowIndex = "Starting. . ."; // 打开单个弹窗,不再重复创建 const htmlOutput = HtmlService.createHtmlOutputFromFile('html_file'); ui.showModelessDialog(htmlOutput, "Extracting Test Cases"); // .....Some Code...... // 处理每行数据 values.forEach((row, rowIndex) => { // 更新全局变量为当前行索引 currentRowIndex = rowIndex; // .....Some Code...... let dialogCount = 1; while ((match = regex.exec(testCaseText)) !== null) { // .....Some Code...... let endTime = new Date(); const elapsedSeconds = endTime - _startTime; Utilities.sleep(500); // 可选:更新弹窗标题 ui.showModelessDialog(htmlOutput, `EXTRACT - Row ${rowIndex + 1} - Dialog ${dialogCount}`); SpreadsheetApp.flush(); Utilities.sleep(500); dialogCount++; } // .....Some Code...... }); // 循环结束后标记完成 currentRowIndex = "Done"; // .....Some Code...... } // 供客户端调用的方法,返回当前rowIndex function getCurrentRowIndex() { return currentRowIndex; }
核心逻辑说明
- 用全局变量
currentRowIndex实时存储当前处理的行索引,客户端通过google.script.run定期拉取该值。 - 保持单个弹窗打开,避免重复创建弹窗导致的内容覆盖问题。
- 客户端通过
setTimeout定时触发更新,确保实时同步服务器端的处理状态。
内容的提问来源于stack exchange,提问作者Nishant Bharwani
相关产品推荐
相关产品推荐

