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

Google Apps Script发送邮件时如何嵌入格式化的表格

问题描述

我目前编写了一段可通过邮件发送电子表格摘要的Google Apps Script代码,现需要将另一张工作表的摘要表格添加到该邮件中:待添加的工作表是其他工作表的筛选结果,仅保留日期与B1单元格日期相等的行,我希望提取该表中所有非空行组成的表格,添加到邮件正文中。
我尝试编写的实现代码如下:

function myFunction() {
   var ss = SpreadsheetApp.getActiveSpreadsheet();
  var responses = ss.getSheetByName("cambios mail");
  var mail = ss.getSheetByName("MAILS");
  var active_range = responses.getActiveRange();
  var cambio = responses.getRange(active_range.getRowIndex(), 5).getValue();
  var nuevo = responses.getRange(3, 11).getValue();
  var cancelados = responses.getRange(3, 12).getValue();
  var fecha =responses.getRange(3, 8).getValue();
  var date = Utilities.formatDate(fecha, "GMT+2", "dd/MM/YYYY")
 var sheet = ss.getSheetByName('cambios drop');
 var values = sheet.getRange("A2:I" + sheet.getLastRow()).getValues();
 var tabla= JSON.stringify(values);
var subject = "CAMBIOS REFERENCIAS: Resumen refes canceladas/añadidas";
    var body = "Los siguientes modelos fueron modificados en el Master Doc ayer fecha " +date +".\n\n" + "Refes añadidas:" + nuevo + "\n\nRefes canceladas:"+ cancelados+ "\n\nCualquier consulta podéis contestar a este mail."+"\n\nAdjunto una tabla con los cambios de drops de ayer. Si no hubo cambios, la tabla aparecerá vacía."+"\n\nTabla"+ tabla+  "\n\nArchivo: https://docs.google.com/spreadsheets/d/";
   var mailCorrecto = mail.getRange(1,2).getValues()
    GmailApp.sendEmail(mailCorrecto, subject, body);
}

运行上述代码后,邮件中的表格显示为序列化的JSON字符串格式,无法以正常表格样式展示:

  • 原待插入表格样式参考:原待插入表格样式
  • 邮件实际显示效果参考:邮件错误显示效果

需要解决的问题:如何对选取的单元格区域数据进行格式处理,过滤空行后让其在邮件中以可读的正常表格形式展示?

解决方案

问题核心原因有两点:

  1. 使用JSON.stringify(values)直接将二维数组转为JSON字符串,本身不具备表格渲染能力
  2. Gmail纯文本邮件不支持表格样式渲染,需要发送HTML格式邮件正文,将筛选后的数据拼接为标准HTML table结构,同时前置完成空行过滤、日期匹配逻辑。

修改后的完整可运行代码如下:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var responses = ss.getSheetByName("cambios mail");
  var mail = ss.getSheetByName("MAILS");
  var active_range = responses.getActiveRange();
  var cambio = responses.getRange(active_range.getRowIndex(), 5).getValue();
  var nuevo = responses.getRange(3, 11).getValue();
  var cancelados = responses.getRange(3, 12).getValue();
  var fecha = responses.getRange(3, 8).getValue();
  var date = Utilities.formatDate(fecha, "GMT+2", "dd/MM/yyyy");
  
  // 读取目标工作表数据
  var sheet = ss.getSheetByName('cambios drop');
  var headers = sheet.getRange("A1:I1").getValues()[0];
  var allValues = sheet.getRange("A2:I" + sheet.getLastRow()).getValues();
  // 读取B1目标日期,统一格式化避免时区、日期对象匹配误差
  var targetDate = Utilities.formatDate(sheet.getRange("B1").getValue(), "GMT+2", "dd/MM/yyyy");
  
  // 过滤数据:排除全空行 + 匹配目标日期
  // 注:默认日期在A列,若日期列位置不同修改row[0]的下标即可,数组下标从0开始计数
  var filteredRows = allValues.filter(row => {
    var isEmpty = row.every(cell => cell === '' || cell === null);
    if (isEmpty) return false;
    var rowDate = Utilities.formatDate(new Date(row[0]), "GMT+2", "dd/MM/yyyy");
    return rowDate === targetDate;
  });

  // 拼接带基础样式的HTML表格
  var tablaHtml = `<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse;">`;
  // 拼接表头
  tablaHtml += `<tr style="background:#f0f0f0;font-weight:bold;">`;
  headers.forEach(header => {
    tablaHtml += `<td>${header}</td>`;
  });
  tablaHtml += `</tr>`;
  // 拼接内容行
  filteredRows.forEach(row => {
    tablaHtml += `<tr>`;
    row.forEach(cell => {
      // 日期类型单元格统一格式化,避免显示时间戳
      var cellValue = cell instanceof Date ? Utilities.formatDate(cell, "GMT+2", "dd/MM/yyyy") : cell;
      tablaHtml += `<td>${cellValue || ''}</td>`;
    });
    tablaHtml += `</tr>`;
  });
  tablaHtml += `</table>`;
  // 无匹配数据时显示提示
  if (filteredRows.length === 0) {
    tablaHtml = `<p>*昨日无drop变更记录</p>`;
  }

  var subject = "CAMBIOS REFERENCIAS: Resumen refes canceladas/añadidas";
  // 纯文本正文兜底,适配不支持HTML的邮件客户端
  var plainBody = `Los siguientes modelos fueron modificados en el Master Doc ayer fecha ${date}.

Refes añadidas: ${nuevo}

Refes canceladas: ${cancelados}

Cualquier consulta podéis contestar a este mail.

Adjunto una tabla con los cambios de drops de ayer. Si no hubo cambios, la tabla aparecerá vacía.
Tabla: ${filteredRows.length === 0 ? '无变更记录' : '请查看HTML格式邮件查看表格'}

Archivo: https://docs.google.com/spreadsheets/d/${ss.getId()}`;
  // HTML格式正文
  var htmlBody = `
  <p>Los siguientes modelos fueron modificados en el Master Doc ayer fecha <b>${date}</b>.</p>
  <p>Refes añadidas: <b>${nuevo}</b></p>
  <p>Refes canceladas: <b>${cancelados}</b></p>
  <p>Cualquier consulta podéis contestar a este mail.</p>
  <p>Adjunto una tabla con los cambios de drops de ayer. Si no hubo cambios, la tabla aparecerá vacía.</p>
  <h4>Tabla de cambios</h4>
  ${tablaHtml}
  <p>Archivo: <a href="https://docs.google.com/spreadsheets/d/${ss.getId()}">点击跳转至在线表格</a></p>
  `;
  // 修复原代码bug:用getValue()直接读取邮箱字符串,避免传入二维数组
  var mailCorrecto = mail.getRange(1,2).getValue();
  // 发送带HTML正文的邮件
  GmailApp.sendEmail(mailCorrecto, subject, plainBody, {
    htmlBody: htmlBody
  });
}
关键修改点说明
  • 移除JSON.stringify的错误用法,改用HTML table标签拼接表格,添加边框、内边距、表头背景等基础样式,保证在各类邮件客户端中显示正常
  • 新增双层过滤逻辑:先剔除整行全空的无效行,再将行日期和B1目标日期统一格式化后做匹配,避免日期对象、时区差异导致的匹配错误
  • 调用GmailApp.sendEmail时传入第四个参数htmlBody指定HTML格式正文,同时保留纯文本正文做兼容
  • 修复原代码的逻辑bug:读取收件人邮箱时用getValue()替代getValues()直接获取字符串值,自动补全原代码缺失的表格ID生成可点击的文件跳转链接
  • 对日期类型单元格做统一格式化处理,避免出现时间戳、日期显示错乱的问题

提示:如果你的筛选日期不在A列,只需要修改过滤逻辑里row[0]的下标即可,比如日期在C列就改为row[2]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:39:17