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

forEach结合HTML模板批量发邮件时数据无法识别的问题

问题描述

我编写了一段Google Apps Script脚本,想从电子表格中获取多行数据,为每行数据发送一封邮件。但运行data.forEach()循环时,HTML模板无法识别循环中的value参数,导致模板内的value.name和value.score无法正常渲染。

数据示例

StudentScore
Robert8
David6
Frank9

现有脚本代码

function sendMultipleEmails() {
    const rawData = ss.getRange("A1:B3").getValues();
    let data = [];
    // 比起表格的二维数组,我更喜欢用对象字面量
    rawData.forEach(value => {
        data.push({
            name: value[0],
            score: value[1],
        })
    })
    data.forEach(value => {
        let emailTo = "example@gmail.com";
        // 这里的value.name能正常用,因为是在代码里直接设置的
        let subject = `Scores for ${value.name}`;
        let body = HtmlService.createTemplateFromFile("scores");
        let message = body.evaluate().getContent();
        let options = {
            htmlBody: message,
        }
        GmailApp.sendEmail(emailTo, subject, body, options)
    })
}

现有HTML模板代码

<h2> Hey <?= value.name ?> </h2>
<p>This is your score <?= value.score?></p>

解决方法

核心问题是你没有把循环中的value对象传递给HTML模板——模板有独立作用域,无法直接访问脚本循环里的变量,必须显式把数据挂载到模板对象上。

1. 传递数据到模板

创建模板后,把当前循环的学生数据赋值给模板的属性:

let body = HtmlService.createTemplateFromFile("scores");
// 将当前学生数据挂载到模板上
body.student = value;

2. 修改模板变量引用

把模板里的value.name、value.score改成对应模板属性的student.name、student.score:

<h2> Hey <?= student.name ?> </h2>
<p>This is your score <?= student.score?></p>

3. 修复邮件发送参数错误

原代码中GmailApp.sendEmail的第三个参数传了模板对象body,这是错误的,应该传入纯文本版本的备用邮件内容:

// 第三个参数替换为纯文本内容,作为HTML邮件的降级备选
GmailApp.sendEmail(emailTo, subject, `Hey ${value.name}, your score is ${value.score}`, options)

优化后的完整脚本

function sendMultipleEmails() {
    const ss = SpreadsheetApp.getActiveSpreadsheet(); // 补充ss的定义,原代码遗漏会报错
    const rawData = ss.getRange("A1:B3").getValues();
    // 用map直接转换数组,比forEach+push更简洁
    const data = rawData.map(row => ({
        name: row[0],
        score: row[1]
    }));

    data.forEach(student => {
        const emailTo = "example@gmail.com";
        const subject = `Scores for ${student.name}`;
        const template = HtmlService.createTemplateFromFile("scores");
        template.student = student;
        const message = template.evaluate().getContent();
        
        const options = {
            htmlBody: message
        };
        GmailApp.sendEmail(emailTo, subject, `Hey ${student.name}, your score is ${student.score}`, options);
    });
}

额外优化点

  • 用map替代forEach+push转换数组,代码更简洁
  • 补充ss的声明(原代码未定义会触发报错)
  • 用const替代不必要的let,提升代码严谨性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:39:54