You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Google Apps Script取结果数组生成HTML行及表单功能异常排查

解决方案:Google Apps Script 数组数据驱动动态HTML表格行

问题核心

需要实现一个确认界面,从GAS获取结果数组并生成对应HTML行,同时解决两个矛盾:

  • 纯前端JS动态生成:可按需生成多行,但form_data()函数偶尔失效
  • GAS拼接HTML字符串:form_data()稳定,但无法灵活生成多行

解决思路

采用GAS模板HTML + 数据传递的方案,既保留GAS对HTML渲染的稳定性,又通过模板语法实现动态行生成,同时修复form_data()的潜在语法错误。

步骤1:创建HTML模板文件(命名为PurgeConfirmation.html)

把静态HTML结构、样式引用、JS逻辑统一放在模板里,用模板语法插入GAS传递的数据,遍历数组生成表格行:

<?!= HtmlService.createHtmlOutputFromFile('StyleSheet').getContent(); ?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table width="100%">
  <tr>
    <th class="fitwidth">IDs</th>
    <th class="fitwidth">Names</th>
    <th>Quantities</th>
    <th style="width:21px"><div class="note1"><a title="Check the ones you want to confirm">✔</a></div></th>
    <th style="width:21px"><div class="note2"><a title="Check the ones you want to redo">✖</a></div></th>
  </tr>
  <? results.forEach((item, index) => { ?>
  <tr align="center">
    <td class="fitwidth"><?= item[0] ?></td>
    <td class="fitwidth"><?= item[1] ?></td>
    <td><?= item[2] ?></td>
    <td><input type="radio" name="<?= index ?>" value="confirm" checked></td>
    <td><input type="radio" name="<?= index ?>" value="redo"></td>
  </tr>
  <? }) ?>
</table>
<input type="button" value="Submit" class="action" onclick="form_data()">
<input type="button" value="Close" onclick="google.script.host.close()">
<script>
  function form_data(){
    var values = {};
    <? results.forEach((_, index) => { ?>
      values[<?= index ?>] = $(`input[name='<?= index ?>']:checked`).val();
    <? }) ?>
    google.script.run.withSuccessHandler(() => {
      google.script.host.close();
    }).filter(values);
  }
</script>

步骤2:修改GAS中的purge函数

移除手动拼接HTML的逻辑,改用模板文件传递处理好的结果数组:

function purge() {
  // 保留原有数据处理逻辑
  const mes = ['1234','x1','5678','x2','9012','x3'];
  const mesID = mes.filter((e,i) => i % 2 == 0);
  
  const data = dataSS.getRange(3,1,dataSS.getRange("A3:B").getValues().filter(e => e[0] || e[1]).length,2).getValues();
  
  const mesGroups = mes.reduce((r, e, i) => (i % 2 ? r[r.length - 1].push(e) : r.push([e])) && r, []);
  const mesGroupsQuantities = mesGroups.filter(e => data.flat().includes(e[0])).concat(mesGroups.filter(e => !data.flat().includes(e[0])));
  const ifNameNotFound = mesID.map(e => [e,"Please Check ID"]).filter(e => !data.flat().includes(e[0]));

  const sortArray = (mesID, data) => {
    data.sort((a, b) => {
      const aIndex = a[0];
      const bIndex = b[0];
      return mesID.indexOf(aIndex) - mesID.indexOf(bIndex);
    });
  };
  sortArray(mesID, data);
  
  const names = data.filter(e => mesID.includes(e[0])).concat(ifNameNotFound);

  var results = [];
  for(var i = 0;i < names.length;i++) {
    results.push([names[i][0],names[i][1],mesGroupsQuantities[i][1]]);
  }

  // 改用模板HTML传递数据
  const template = HtmlService.createTemplateFromFile('PurgeConfirmation');
  template.results = results; // 将结果数组注入模板
  const html = template.evaluate().setWidth(600).setHeight(300);
  
  SpreadsheetApp.getUi().showModelessDialog(html,"Preview Purge List:");
}

function filter(values){
  const submission = Object.entries(values);
  console.log(submission);
}

关键修复点

  1. 修复JS语法错误:原代码拼接JS对象时最后一个属性会多逗号,导致form_data()偶尔失效,模板循环生成属性可避免此问题
  2. 分离数据与视图:GAS负责数据处理,HTML模板负责渲染,既保证稳定性又支持动态多行生成
  3. 优化异步逻辑:在google.script.run的成功回调中关闭对话框,确保请求完成后再关闭,避免请求中断

内容的提问来源于stack exchange,提问作者Mochi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:01:17