【问题标题】:How to copy data from Gmail message attachment to a spreadsheet?如何将数据从 Gmail 邮件附件复制到电子表格?
【发布时间】:2019-07-26 13:47:52
【问题描述】:

我正在尝试从 CSV 报告中获取数据,该报告位于共享电子邮件的特定文件夹中,并将 Google 表格中特定标签中的旧数据替换为新数据。

我已经尝试了不同的解决方案,但似乎没有一个能将我带到我想要的地方。下面的代码是我生成的最干净的代码,但由于某种原因,它什么也没做。

我遵循的步骤:

  1. 打开文件夹所在的邮箱(是共享邮箱,在Gmail中管理)
  2. 搜索所在文件夹(label:rpt-its-all-data)
  3. 记录最后收到的电子邮件
  4. 打开电子邮件/附件
  5. 获取数据
  6. 按 ID 打开 Google 表格
  7. 用当前日期更新选项卡 INFO 中单元格 B1 中的日期(我什至没有尝试对这个进行排序)
  8. 打开选项卡 ALLDATA
  9. 在选项卡 ALLDATA 中粘贴值

这是一份谷歌表格查看格式:https://docs.google.com/spreadsheets/d/1GyGxSwUtITeje0-Qx63rB8xChMSbLvn1FDCOKOJITio/edit?usp=sharing

我已经尝试过这段代码:

function importCSVFromGmail() {
    var threads = GmailApp.search("id:AH1rexR2yzlanbk9GyP52tyVKSnXcMDz_miTs1-lLXtJwJB56l2r label:rpt-its-all-data");
    var message = threads[0].getMessages()[0];
    var attachment = message.getAttachments()[0];

    // Is the attachment a CSV file
    if (attachment.getContentType() === "text/csv") {
        var id = "1F_Z_00-ThdTRzlZ3nYd_pieJHkUjgye3pI_KJfydoP4";
        var name = "ALLDATA";
        var sheet = SpreadsheetApp.openById(id);
        var tab = sheet.getSheetByName(name);
      
        // Clear the content of the sheet
        tab.clearContents().clearFormats();
        tab.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
      
        var csvData = tab.Utilities.parseCsv(attachment.getDataAsString(), ",");
    }
}

使用上面的代码,我没有得到任何结果。我不确定为什么会这样。

我认为查询中的邮件 ID 不能正确调用该电子邮件,但我找不到任何其他方法。

【问题讨论】:

  • 您的变量 csvData 似乎有问题。应该在您设置代码值的那一行的上方。

标签: csv google-apps-script google-sheets gmail


【解决方案1】:

我通过这些更改修改了您的代码,使其可以按预期工作:

1) 您遇到了错误,因为必须先声明 csvData 变量才能使用它。此外,parseCsv() 函数来自 Utilities 类,您可以直接使用该类(您这样称呼它:tab.Utilities.parseCsv)[1]。另一个问题是您无法使用消息 ID [2] 搜索消息,因此您应该发出获取请求 [3]。

2) 我放了一个 If 来验证邮件是否有附件。

3)我更改了 If 中的条件以验证它是否是文件名中带有文件扩展名的 csv 文件,因为 gmail API 将带有“application/octet-stream”的 csv 文件作为 mime 类型(我猜这是因为您可以在 gmail 中将其作为 Google 表格打开)。

4) 我修改了您获取消息的方式以获取最后一个线程的最后一条消息,之前它是获取每个线程的第一条消息,而不是最后一条。

5) 在 INFO 表中设置日期,如果需要特定格式[1],可以查看 formatDate 函数。

function importCSVFromGmail() {
  var threads = GmailApp.search("label:rpt-its-all-data");
  var message = threads[0].getMessages().pop();

  var attachment = message.getAttachments()[0];

  if (attachment != null) {
    var attachName = attachment.getName();

    // Is the attachment a CSV file
    if (attachName.substring(attachName.length-4) === ".csv") {
      var id = "1bvENjFYC48LSYDMPtI4FIOKIChiuIrg5O4WRziFeAhU";
      var name = "ALLDATA";
      var sheet = SpreadsheetApp.openById(id);
      var tab = sheet.getSheetByName(name);
      var tabInfo = sheet.getSheetByName("INFO");
      tabInfo.getRange("B1").setValue(new Date());

      // Clear the content of the sheet
      tab.clearContents().clearFormats();
      var csvData = Utilities.parseCsv(attachment.getDataAsString(), ",");
      tab.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
    }
  } 
}

[1]https://developers.google.com/apps-script/reference/utilities/utilities#formatDate(Date,String,String)

[2]https://support.google.com/mail/answer/7190

[3]https://developers.google.com/gmail/api/v1/reference/users/messages/get

【讨论】:

  • 太棒了。谢谢安德烈斯。还有一件事。正如我在最初的帖子中最初提到的那样,报告将进入一个共享的公司邮箱,在 Gmail 中运行。如何获取该邮箱的 ID 以让脚本在其中查找该电子邮件?
  • 您可以使用群组成员电子邮件运行脚本并获取消息表单/发送到群组,将查询字符串更改为:“label:rpt-its-all-data {from:group@ email.com 或发送至:group@email.com}"
  • 谢谢安德烈斯!非常感谢您的时间、耐心和支持。现在我有另一个问题。当我尝试运行脚本时,它又没有做任何事情。我认为原因是需要复制的数据大小,因为我们谈论的是 300.000 到 800.000 个单元格,所以文件很大,关于如何传递这个有什么想法吗?非常感谢您的所有帮助。 :)
  • 可能会花费很多时间,是否有消息错误?您可以发布另一个问题,其中包含有关所解释问题的所有信息。
  • 没有错误消息,我让它工作了几个小时。我也看不到调试。它开始,然后立即下降。
猜你喜欢
  • 2014-01-05
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 2019-08-27
  • 2012-09-23
相关资源
最近更新 更多