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

使用Apps Script从谷歌表格发带PDF附件邮件报错求助

解决Google Apps Script发送邮件附件时的迭代器报错问题

问题描述

原本代码可从谷歌表格自动发送邮件,添加附件相关逻辑(第9、18、21行)后,持续触发报错:

Exception: Cannot retrieve the next object: iterator has reached the end.
SendMails @ Code.gs:21

已启用Google Drive API,最初用getFolderByName替代第9行的getFolderById时也出现相同问题,原代码如下:

function SendMails() {
  var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
  var wrkShtEmailIDs= wrkBk.getSheetByName("Email_ID");
  var wrkShtMessage= wrkBk.getSheetByName("Mail_Details");
  var subject = wrkShtMessage.getRange('A2').getValue();
  var message = wrkShtMessage.getRange('B2').getValue();

  var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');

  for (var i=41;i<43;i++){
    var fname = wrkShtEmailIDs.getRange('A' + i).getValue();
    var lname = wrkShtEmailIDs.getRange('B' + i).getValue();
    var emailAddress = wrkShtEmailIDs.getRange('C' + i).getValue();
    var fileName = wrkShtEmailIDs.getRange('D' + i).getDisplayValue();
    var file = folder.getFilesByName(fileName);
    var finalmsg = "";
    finalmsg = fname + "\n" + message;
    MailApp.sendEmail(emailAddress, subject, finalmsg, {attachments:[file.next().getAs(MimeType.PDF)]})
  }
}

报错原因

DriveApp.getFilesByName(fileName)返回的是文件迭代器而非单个文件:

  • 当指定名称的文件不存在于目标文件夹时,迭代器无内容,直接调用file.next()会触发「迭代器已到末尾」的报错;
  • 即使存在同名文件,也需先确认迭代器有内容再调用next(),避免意外报错。

修复方案

1. 基础修复:检查文件存在性

在调用next()前,用hasNext()判断迭代器是否有内容,不存在时跳过或记录错误:

function SendMails() {
  var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
  var wrkShtEmailIDs= wrkBk.getSheetByName("Email_ID");
  var wrkShtMessage= wrkBk.getSheetByName("Mail_Details");
  var subject = wrkShtMessage.getRange('A2').getValue();
  var message = wrkShtMessage.getRange('B2').getValue();

  var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');

  for (var i=41;i<43;i++){
    var fname = wrkShtEmailIDs.getRange('A' + i).getValue();
    var lname = wrkShtEmailIDs.getRange('B' + i).getValue();
    var emailAddress = wrkShtEmailIDs.getRange('C' + i).getValue();
    var fileName = wrkShtEmailIDs.getRange('D' + i).getDisplayValue();
    var fileIterator = folder.getFilesByName(fileName);
    var finalmsg = fname + "\n" + message;

    // 检查是否找到对应文件
    if (fileIterator.hasNext()) {
      var targetFile = fileIterator.next();
      MailApp.sendEmail(emailAddress, subject, finalmsg, {
        attachments: [targetFile.getAs(MimeType.PDF)]
      });
    } else {
      // 文件不存在时的处理逻辑,可根据需求调整
      console.log(`未找到文件:${fileName},跳过发送给${emailAddress}的邮件`);
      wrkShtEmailIDs.getRange('E' + i).setValue(`错误:未找到文件${fileName}`);
    }
  }
}

2. 进阶优化建议

  • 提升性能:批量读取数据:原代码循环内多次调用getRange会拖慢执行速度,建议一次性读取整段数据:
    // 替换循环内的单个getRange调用
    var dataRange = wrkShtEmailIDs.getRange(41, 1, 2, 4); // 从第41行开始,读取2行4列数据
    var data = dataRange.getValues();
    for (var i=0;i<data.length;i++){
      var fname = data[i][0];
      var lname = data[i][1];
      var emailAddress = data[i][2];
      var fileName = data[i][3];
      // 后续文件检查、发送逻辑不变
    }
    
  • 处理同名多文件:如果文件夹中有多个同名文件,可收集所有文件作为附件:
    var attachments = [];
    while (fileIterator.hasNext()) {
      attachments.push(fileIterator.next().getAs(MimeType.PDF));
    }
    if (attachments.length > 0) {
      MailApp.sendEmail(emailAddress, subject, finalmsg, {attachments: attachments});
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:13:27