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

Google Apps Script 技术问询:批量发送邮件时替换PDF附件为DOCX格式的实现方法

解决Google Apps Script发送DOCX附件的问题

我来帮你搞定这个DOCX附件发送的问题!其实只需要调整两处代码就能解决,下面是具体步骤和修改后的完整代码:

步骤1:替换DOCX文件ID

首先把你云端硬盘里DOCX文件的ID替换到变量里,原来的TERMS_AND_CONDITIONS_ID可以直接复用,或者改个更清晰的名字(比如TERMS_DOCX_ID),只要对应正确的文件ID就行:

// DOCX文件(替换成你的DOCX文件ID)
var TERMS_AND_CONDITIONS_ID = "你的DOCX文件ID";

步骤2:修改邮件附件的获取方式

在send_email函数里,原来的PDF附件代码需要改成DOCX的格式。其实不需要转换格式,直接获取DOCX文件的Blob对象即可,因为MailApp支持直接发送DOCX格式的附件:

MailApp.sendEmail({
  to: get_email(spreadsheet, participant_row),
  subject: get_subject(),
  body: "",
  htmlBody: get_body(get_name(spreadsheet, participant_row), spreadsheet, participant_row),
  inlineImages: {sampleImage: img1.getBlob(), sampleImage2: img2.getBlob()},
  attachments: [DriveApp.getFileById(TERMS_AND_CONDITIONS_ID).getBlob()] // 直接获取DOCX的Blob对象
});

如果你想明确指定MIME类型,也可以写成:

attachments: [DriveApp.getFileById(TERMS_AND_CONDITIONS_ID).getAs(MimeType.MICROSOFT_WORD)]

不过getBlob()已经会自动返回对应文件的正确MIME类型,所以两种方式都可以。

修改后的完整代码

下面是整合了上述修改的完整代码,我已经把关键修改处用注释标出来了:

// Excel表格列数从1开始计数
var email_position = 7;
var firstname_position = 1;
var lastname_position = 2;
var yesno_position = 11;
var sheet_name="Sheet1";

// 文档ID获取方式:打开云端硬盘 -> 选择文档 -> 获取链接 -> 提取/d/与/view?之间的部分
// DOCX文件(替换成你的DOCX文件ID)
var TERMS_AND_CONDITIONS_ID = "你的DOCX文件ID";

// 图片文件
var IMAGE_1_ID = "1VZP8m0mpqoGTMNrDJjnKnwaAUtgNHXVA";
var IMAGE_2_ID = "18fxaA1-oylleZ4W8E9tF0yr2p-uYN_O4";

// 邮件相关
var EMAIL_SUBJECT = "SUBJECT";
// 请自行在对应行修改HTML格式的邮件正文

// 主函数
function sendEmail() {
  // 激活"Sheet1"工作表并设为当前活动表
  SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_name).activate();
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  // 获取最后一行的索引
  var last_row = spreadsheet.getLastRow();

  // 检查今日是否还能发送邮件
  if(check_emails_status() == 1) {
    return;
  }

  // 获取附件
  // 通过云端硬盘文件ID获取文件
  var docxFile = DriveApp.getFileById(TERMS_AND_CONDITIONS_ID); // 修改:获取DOCX文件对象
  var img1 = DriveApp.getFileById(IMAGE_1_ID);
  var img2 = DriveApp.getFileById(IMAGE_2_ID);

  // 为每位收件人发送邮件
  for(var participant_row = 2; participant_row <= last_row; ++participant_row) {
    // 检查是否已向该用户发送过邮件
    if(check_already_sent(spreadsheet, participant_row) == 1) {
      continue;
    }

    // 检查重复邮箱
    if(participant_row < last_row && get_email(spreadsheet,participant_row).localeCompare(get_email(spreadsheet,participant_row+1)) == 0)
      continue;

    // 检查谷歌邮件发送限额是否已用完
    if(MailApp.getRemainingDailyQuota() <= 0) {
      log_errors();
      break;
    }

    // 发送邮件
    send_email(spreadsheet, participant_row, img1, img2, docxFile); // 修改:传入DOCX文件对象

    // 标记该用户已接收邮件,避免重复发送
    spreadsheet.getRange(participant_row, yesno_position).setValue("YES");

    // 同时标记重复邮箱为已发送
    var nr_of_duplicates = count_duplicate(spreadsheet, participant_row, last_row);
    for(var i=1; i<=nr_of_duplicates;i++) {
      var get_value = spreadsheet.getRange(participant_row,yesno_position).getValue();
      spreadsheet.getRange(participant_row - i, yesno_position).setValue(get_value);
    }
  } // 循环结束
}

// 检查今日剩余可发送邮件数量
// Google Apps Script的限额为24小时内100封邮件!
function check_emails_left() {
  var EMAILS_ABLE_TO_SEND_TODAY_LEFT = MailApp.getRemainingDailyQuota();
  Logger.log("今日剩余可发送邮件数:" + EMAILS_ABLE_TO_SEND_TODAY_LEFT.toString());
  return EMAILS_ABLE_TO_SEND_TODAY_LEFT;
}

// 检查今日是否还能发送邮件
function check_emails_status() {
  var EMAILS_ABLE_TO_SEND_TODAY_LEFT = check_emails_left();
  if(EMAILS_ABLE_TO_SEND_TODAY_LEFT == 0) {
    Logger.log("警告:今日邮件发送限额已用完,无法继续发送!");
    Browser.msgBox("警告:今日邮件发送限额已用完,无法继续发送!");
    return 1;
  } else {
    return 0;
  }
}

// 获取收件人邮箱
function get_email(spreadsheet, participant_row) {
  // 参数:行号,列号
  return spreadsheet.getRange(participant_row, email_position).getValue();
}

// 获取收件人姓名
function get_name(spreadsheet, participant_row) {
  // 名 + 姓
  return spreadsheet.getRange(participant_row, firstname_position).getValue() + " " + spreadsheet.getRange(participant_row, lastname_position).getValue();
}

// 避免向同一用户重复发送邮件
function check_already_sent(spreadsheet, participant_row) {
  var bool_alreadySentEmail = spreadsheet.getRange(participant_row, yesno_position).getValue();
  if(bool_alreadySentEmail.toString().toUpperCase() == "YES") {
    Logger.log("跳过已发送用户:" + spreadsheet.getRange(participant_row, email_position).getValue());
    return 1;
  } else {
    Logger.log("正在向以下用户发送邮件:" + spreadsheet.getRange(participant_row, email_position).getValue());
    return 0;
  }
}

// 生成邮件主题
function get_subject() {
  return EMAIL_SUBJECT;
}

// 当今日邮件限额用完时显示错误信息
function log_errors() {
  Logger.log("警告:今日邮件发送限额已用完!尚未发送邮件的用户为:" + NAME + "!");
  Browser.msgBox("警告:今日邮件发送限额已用完!尚未发送邮件的用户为:" + NAME + "!");
}

// 向单个用户发送邮件
function send_email(spreadsheet, participant_row, img1, img2, docxFile) { // 修改:参数改为docxFile
  MailApp.sendEmail({
    to: get_email(spreadsheet, participant_row),
    subject: get_subject(),
    body: "",
    htmlBody: get_body(get_name(spreadsheet, participant_row), spreadsheet, participant_row),
    inlineImages: {sampleImage: img1.getBlob(), sampleImage2: img2.getBlob()},
    attachments: [docxFile.getBlob()] // 修改:添加DOCX附件的Blob对象
  });
}

// 检查表格中的重复邮箱条目
function count_duplicate(spreadsheet, participant_row, last_row) {
  var duplicates = 0;
  var counter = 1;
  for(var i = participant_row; i >=0 ; i--)
    if(get_email(spreadsheet, participant_row).localeCompare(get_email(spreadsheet, participant_row - counter)) == 0) {
      duplicates++;
      counter++;
    } else break;
  return duplicates;
}

// 生成HTML格式的邮件正文
function get_body(NAME, spreadsheet, participant_row) {
  return "HTML TEXT <img src=\"cid:sampleImage\" width=200 height=200><img src=\"cid:sampleImage2\" width=200 height=200>"
}

为什么这样可行?

Google Apps Script的DriveApp.getFileById()获取到的文件对象,调用getBlob()会直接返回该文件的原始二进制数据,MailApp的attachments参数接受Blob对象数组,所以DOCX文件可以直接作为附件发送,不需要额外的格式转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:32:45