Можно ли экспортировать таблицу из тела Gmail с сохранением формата в листы Google с помощью GAS?

Я пытаюсь получить данные из тела Gmail, используя GAS. Чтобы быть конкретным, я получаю электронное письмо с содержимым таблицы; Я пытаюсь скопировать таблицу из gmail и записать ее в лист Google для дальнейшего анализа. Ниже приведен пример письма, которое я получаю:

Результат, который я ожидаю в листах Google:

ОБНОВЛЕНИЕ: я смог внести некоторые изменения в код, который у меня был, обратившись к Вставить таблицу из gmail в электронную таблицу Google с помощью скрипта Google

Вот как теперь выглядит тело письма и вывод. Электронная почта:

Выход GSheet:

Проблема возникает при объединении ячеек в таблице. Код не генерирует выходные данные так, как они отображаются в теле письма Gmail. Есть ли обходной путь для этого?

Окончательный код:

var SEARCH_QUERY = "SearchKey";

function getEmailss_(q) {
    var emails = [];
    var threads = GmailApp.search(q);
    if (threads.length == 0) {
      console.info("No threads found that match the search query: " + q);
    }
    for (var i in threads) {
        var msgs = threads[i].getMessages();
        for (var j in msgs) {
            var arrStr = msgs[j].getBody()
              .replace(/</tr>/gm, '[/tr]')
              .replace(/</td>/gm, '[/td]')
              .replace(/<.*?>/g, '\n')
              .replace(/^\s*\n/gm, '')
              .replace(/^\s*/gm, '')
              .replace(/\s*\n/gm, '\n')
              .split("[/tr]");
            if (arrStr.length == 1) {
              console.info("No data found in thread: " + threads[i].getFirstMessageSubject());
            }
            var line = [];

            for (var i = 0; i < arrStr.length - 1; i++) {

              line = arrStr[i].split("[/td]");
              line.length -= 1;
              emails.push(line);
            }
        }
    }
    if (emails.length == 0) {
      console.info("No emails found that match the search query: " + q);
    }
    return convert2ArrayToRectangular_(emails);
}

function convert2ArrayToRectangular_(array2d)
{
  // get max width
  var res = [];
  var w = 0;
  for (var i = 0; i < array2d.length; i++)
  {
    if (array2d[i].length > w) {w = array2d[i].length;}    
  }

  var row = [];
  for (var i = 0; i < array2d.length; i++)
  {
    row = array2d[i];
    if (array2d[i].length < w)
    {
      for (var ii = array2d[i].length; ii < w; ii++)
      {
        row.push('');        
      }  
    }
    res.push(row);
  }
  return res;
}


function appendData_(sheet, array2d) {
    var h = array2d.length;
    var l = array2d[0].length;
    sheet.getRange(1, 1, h, l).setValues(array2d);
 } 

function saveEmailsss() {
    var array2d = getEmailss_(SEARCH_QUERY);
    if (array2d) {
        appendData_(SpreadsheetApp.getActive().getSheetByName('Sheet1'), convert2ArrayToRectangular_(array2d));
    }
    markArchivedAsRead();
}

function markArchivedAsRead() {
    var threads = GmailApp.search('label:inbox is:unread to:me subject:importnumberlist');
    GmailApp.markThreadsRead(threads);
};

Непонятно, в чем разница между верхним и нижним изображениями. Пожалуйста, опишите спецификацию дизайна таблицы, используя текст.

Rubén 10.01.2023 17:56

Имейте в виду, что сообщения в Gmail форматируются с использованием HTML, а в Google Таблицах используются методы SpreadsheetApp.Range.

Rubén 10.01.2023 18:03

Первое изображение — это превью из Gmail. Это пример того, как я получаю электронное письмо. Во-вторых, я хочу, чтобы эта таблица из Gmail была перенесена в лист Google в разных столбцах и строках.

Gitz 10.01.2023 18:22

Отвечает ли это на ваш вопрос? Вставить таблицу из gmail в гугл-таблицу с помощью гугл-скрипта

Lorena Gomez 10.01.2023 20:26

Привет, Лорена, внесла изменения в мой вопрос. Да, другой вопрос был в значительной степени полезен; но теперь столкнулся с новой проблемой. Пожалуйста, обратитесь к моему обновленному вопросу - если бы вы могли указать, что можно сделать с этим, это было бы очень полезно.

Gitz 11.01.2023 07:40

Хотя я не уверен, правильно ли я понял ваш вопрос, я предложил ответ. Пожалуйста, подтвердите это. Если я неправильно понял ваш вопрос и это было бесполезно, приношу свои извинения.

Tanaike 11.01.2023 08:15
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
0
6
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В качестве другого подхода, как насчет использования Sheets API? При использовании API Sheets таблицу HTML можно анализировать, включая объединенные ячейки. Пример сценария выглядит следующим образом.

Пример сценария:

Этот скрипт использует API листов. Пожалуйста, включите API Таблиц в расширенных сервисах Google.

var SEARCH_QUERY = "SearchKey";

function getEmailss_(q, sheetName) {
  var emails = [];
  var threads = GmailApp.search(q);
  if (threads.length == 0) {
    console.info("No threads found that match the search query: " + q);
  }
  var tables = [];
  for (var i in threads) {
    var msgs = threads[i].getMessages();
    for (var j in msgs) {
      var arrStr = msgs[j].getBody();
      var table = arrStr.match(/<table[\s\S\w]+?</table>/);
      if (table) {
        tables.push(table[0]);
      }
    }
  }
  if (emails.length == 0) {
    console.info("No emails found that match the search query: " + q);
  }
  if (tables.length == 0) {
    console.info("No tables.");
    return
  };
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetName);
  var requests = [{ pasteData: { html: true, data: tables.join(""), coordinate: { sheetId: sheet.getSheetId() } } }];
  Sheets.Spreadsheets.batchUpdate({ requests }, ss.getId());
}

function saveEmailsss() {
  var sheetName = "Sheet1"; // Please set your sheet name.
  getEmailss_(SEARCH_QUERY, sheetName);
  markArchivedAsRead();
}
  • При запуске этого скрипта HTML-таблица, включенная в сообщение электронной почты, извлекается и помещается в активную электронную таблицу.

Использованная литература:

Удивительно - это сработало! Большое спасибо! нужно было только удалить "if (tables.length == 0) { console.info("Нет таблиц.");" и измените emails.length на table.length в предыдущей строке.

Gitz 11.01.2023 11:29

Привет @Tanaike, у меня был быстрый вопрос. Я использую "sheet.getRange("A1:E").clearContent();" перед «var просит» очистить существующую таблицу и записать новый вывод. Однако я вижу, что после добавления данных они сразу же удаляются, а форматирование таблицы остается. Вы были бы знакомы с такой проблемой? Это вызвано API-интерфейсом листов?

Gitz 16.01.2023 15:23

Кроме того, в качестве временного обходного пути я удаляю первые 4 столбца и добавляю еще 4 столбца, чтобы казалось, что данные обновляются каждый раз при запуске кода. Я использую следующие коды: sheet.deleteColumns(1, 4) sheet.insertColumns(1, 4);

Gitz 16.01.2023 16:21

@Gitz О вашем новом вопросе I had a quick question., я хотел бы поддержать вас. Но, я должен извиниться за мое плохое знание английского языка. К сожалению, я не могу понять ваш новый вопрос. Могу я спросить вас о деталях вашего нового вопроса?

Tanaike 17.01.2023 01:09

Когда я запускаю код, я хочу, чтобы существующие данные были очищены от «Листа1». Новые данные должны быть записаны после этого. Я попытался добавить "sheet.getRange("A1:E").clearContent();" но это не работает.

Gitz 17.01.2023 04:36

@Gitz Спасибо за ответ. Насчет вашего нового вопроса, к сожалению, я пока не могу его понять. Я беспокоюсь, что могу побеспокоить вас, потому что я не могу решить ваши различные вопросы в ближайшее время. Итак, в этом случае я хотел бы порекомендовать опубликовать его как новый вопрос. Таким образом, это поможет многим пользователям найти решение. Если вы можете сотрудничать, чтобы решить ваш новый вопрос, я был бы рад. Можете ли вы сотрудничать, чтобы сделать это?

Tanaike 17.01.2023 06:52

Добавлен новый вопрос - stackoverflow.com/questions/75142872/… Спасибо.

Gitz 17.01.2023 07:58

Другие вопросы по теме