Конвертируйте Google Sheets в отдельные PDF-файлы и отправляйте их по электронной почте

У меня есть электронная таблица, в которой всегда есть лист с именем «Табель рабочего времени», и человек, который его заполняет, может создать столько дополнительных листов заметок, сколько ему нужно.

Мне нужно, чтобы все листы, кроме листа «Табель рабочего времени», были преобразованы в отдельные PDF-файлы и отправлены по электронной почте на адрес.

У меня возникли проблемы с созданием сценария, который не объединяет их в один PDF-файл. Из-за этого он также включает лист «Табель учета рабочего времени» в формате PDF.

Мне нужно, чтобы каждый из листов заметок был преобразован в один PDF-файл, а затем все PDF-файлы были отправлены по электронной почте в виде отдельных вложений. Человек, заполняющий его, также может переименовать заметки во что угодно, поэтому я не могу получить лист по имени.

У меня есть код, который объединяет все листы и переименовывает их, которые я использую для другой цели, я включу его ниже, если он чем-то поможет.

Спасибо заранее за любую помощь

function emailGoogleSpreadsheetAsPDF() {

  // Send the PDF of the spreadsheet to this email address
  var email = "[email protected]"; 

  // Get the currently active spreadsheet URL (link)
  var ss = SpreadsheetApp.getActiveSpreadsheet();

  // Custom
  var name = ss.getRange("Timesheet!J6:K6").getValue();
  var agency = ss.getRange("Timesheet!B4:C4").getValue();

  // Date
  var today = new Date();
  var dd = today.getDate();
  var mm = today.getMonth() + 1; //January is 0!
  var yyyy = today.getFullYear();

  if (dd < 10) {
    dd = '0' + dd;
  }

  if (mm < 10) {
    mm = '0' + mm;
  }

  today = mm + '/' + dd + '/' + yyyy;

  // Subject of email message
  var subject = name + " has Submitted Their Timesheet and Notes"; 

  // Email Body can  be HTML too 
  var body = "This was submitted on " + today;

  var blob = DriveApp.getFileById(ss.getId()).getAs("application/pdf");

  blob.setName(name + "_" + agency + "_" + today + "_" + "timesheet_notes.pdf");

  // If allowed to send emails, send the email with the PDF attachment
  if (MailApp.getRemainingDailyQuota() > 0) 
    GmailApp.sendEmail(email, subject, body, {
      htmlBody: body,
      attachments:[blob]     
    });
}

Просто скройте все листы, которые вам не нужны в pdf.

Cooper 22.05.2019 03:33

Это по-прежнему объединяет их все в один PDF-файл, мне нужно, чтобы каждый лист был отдельным PDF-файлом.

TacoSteve 22.05.2019 16:39

Я собираюсь поработать над этим сегодня утром, потому что я хочу знать, как это сделать.

Cooper 22.05.2019 16:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
291
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Отправка листов электронной таблицы по электронной почте в виде отдельных PDF-файлов

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

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

Кроме того, эти строки - ваша программа, которую мне трудно понять, потому что у вас есть массив из 2 ячеек, но вы используете getValue() вместо getValues();

 var name = ss.getRange("Timesheet!J6:K6").getValue();
 var agency = ss.getRange("Timesheet!B4:C4").getValue();

Вот мой код:

function savePDFFiles1() {
  var ss=SpreadsheetApp.getActive();
  var exclA=['Summary','Images','Globals','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21'];
  var fA=[];
  var html = "";
  var shts=ss.getSheets();
  var pdfFldr=DriveApp.getFolderById('FolderId');//folder where I stored the files temporarily
  for(var i=0;i<shts.length;i++) {
    var sh=shts[i];
    var name=sh.getName();
    if (exclA.indexOf(name)==-1) {
      sh.showSheet();
      for(var j=0;j<shts.length;j++) {
        if (shts[j].getName()!=name) {
          shts[j].hideSheet();
        }
      }
      SpreadsheetApp.flush();//I dont know if this is required
      var file=pdfFldr.createFile(ss.getBlob().getAs('application/pdf').setName(Utilities.formatString('%s_%s.pdf',ss.getName(),name)));
      html+=Utilities.formatString('<br />File: %s Created',file.getName());
      var userInterface=HtmlService.createHtmlOutput(html);
      SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Files Created')                                          
      fA.push(file);
    }
  }
  GmailApp.sendEmail('recipient email', 'Plot Reports', 'Plot Reports Attached', {attachments:fA})
  html+='<br />Email Sent';
  var userInterface=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Files Created');                                          
  for(var i=0;i<fA.length;i++ ) {
    fA[i].setTrashed(true);
  }
  html+='<br />Files Trashed and Process Complete';
  html+='<script>window.onload=function(){google.script.host.close();}</script>';
  var userInterface=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Files Created');                                          
}

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

Я вернусь и посмотрю на обновление вашего сценария сейчас.

Итак, вот как, по моему мнению, будет выглядеть ваш сценарий:

function emailGoogleSpreadsheetAsPDF() {
  var email = "[email protected]"; 
  var ss=SpreadsheetApp.getActive();
  var name=ss.getRange("Timesheet!J6").getValue();//trimmed the range down to match the getValue();
  var agency=ss.getRange("Timesheet!B4").getValue();//same here
  var fldr=DriveApp.getFolderById('folderId');
  var fA=[];
  var today=Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy");
  var subject=Utilities.formatString('%s has Submitted Their Timesheet and Notes',name); 
  var body=Utilities.formatString('This was submitted on %s',today);
  var shts=ss.getSheets();
  for(var i=0;i<shts.length;i++) {
    var sh=shts[i];
    var name=sh.getName();
    sh.showSheet();
    for(var j=0;j<shts.length;j++) {
      if (shts[j].getName()!=name) {
        shts[j].hideSheet();
      }
    }
    SpreadsheetApp.flush();//this may not be necessary...not sure
    var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s_%s_%s_timesheet_notes.pdf', name,agency,today));
    fA.push(file);
  }
  GmailApp.sendEmail(email,subject,body, {attachments:fA});
  for(var i=0;i<fA.length;i++) {
    fA[i].setTrashed(true); 
  }
}

Примечание. Я не тестировал этот последний вариант, поэтому может потребоваться небольшая отладка, но в основном это та же идея, что и в другом примере. Который был протестирован.

Есть еще один способ сделать это, используя UrlFetchApp, который обсуждался здесь. Лично я бы предпочел просто создать файлы и удалить их в конце.

С запрошенными изменениями:

function emailGoogleSpreadsheetAsPDF() {
  var email = "[email protected]";
  var exclA=['TimeSheet'];//and others
  var ss=SpreadsheetApp.getActive();
  var name=ss.getRange("Timesheet!J6").getValue();//trimmed the range down to match the getValue();
  var agency=ss.getRange("Timesheet!B4").getValue();//same here
  var fldr=DriveApp.getFolderById('folderId');
  var fA=[];
  var today=Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy");
  var subject=Utilities.formatString('%s has Submitted Their Timesheet and Notes',name); 
  var body=Utilities.formatString('This was submitted on %s',today);
  var shts=ss.getSheets();
  for(var i=0;i<shts.length;i++) {
    var sh=shts[i];
    var name=sh.getName();
    if (exclA.indexOf(name)==-1) {
      sh.showSheet();
      for(var j=0;j<shts.length;j++) {
        if (shts[j].getName()!=name) {
          shts[j].hideSheet();
        }
      }
      SpreadsheetApp.flush();//this may not be necessary...not sure
      var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s_%s_%s_timesheet_notes.pdf', name,agency,today));
      fA.push(file);
    }
  }
  GmailApp.sendEmail(email,subject,body, {attachments:fA});
  for(var i=0;i<fA.length;i++) {
    fA[i].setTrashed(true); 
  }
  for(var i=0;i<shts.length;i++) {
    if (exclA.indexOf(shts[i].getName())==-1) {
      shts[i].showSheet();
    }
  }
}

Добавление PDF-файла всей электронной таблицы (за исключением исключенных скрытых листов):

function emailGoogleSpreadsheetAsPDF() {
  var email = "[email protected]";
  var exclA=['TimeSheet'];//and others
  var ss=SpreadsheetApp.getActive();
  var name=ss.getRange("Timesheet!J6").getValue();//trimmed the range down to match the getValue();
  var agency=ss.getRange("Timesheet!B4").getValue();//same here
  var fldr=DriveApp.getFolderById('folderId');
  var fA=[];
  var today=Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy");
  var subject=Utilities.formatString('%s has Submitted Their Timesheet and Notes',name); 
  var body=Utilities.formatString('This was submitted on %s',today);
  var shts=ss.getSheets();
  for(var i=0;i<shts.length;i++) {
    var sh=shts[i];
    var name=sh.getName();
    if (exclA.indexOf(name)==-1) {
      sh.showSheet();
      for(var j=0;j<shts.length;j++) {
        if (shts[j].getName()!=name) {
          shts[j].hideSheet();
        }
      }
      SpreadsheetApp.flush();//this may not be necessary...not sure
      var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s_%s_%s_timesheet_notes.pdf', name,agency,today));
      fA.push(file);
    }
  }
  for(var i=0;i<shts.length;i++) {
    if (exclA.indexOf(shts[i].getName())==-1) {
      shts[i].showSheet();
    }
  }
  SpreadsheetApp.flush();//this may not be necessary...not sure
  var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s.pdf',ss.getName()));
  fA.push(file)
  GmailApp.sendEmail(email,subject,body, {attachments:fA});
  for(var i=0;i<fA.length;i++) {
    fA[i].setTrashed(true); 
  }
}

Вау, спасибо, что так внимательно изучили это, я проверю это сегодня вечером, когда вернусь домой. И да, в моем коде могли быть какие-то странные вещи, я не разработчик, поэтому это куча кода, который я нашел в Интернете и сшил вместе. Спасибо еще раз!

TacoSteve 23.05.2019 16:51

Так что до сих пор он работает хорошо, он отправляет мне все PDF-файлы как отдельные лица. Есть две небольшие проблемы, которые я не думаю, что будут серьезные исправления. Во-первых, когда он перебирает все листы, он скрывает остальные. В конце отображается последний лист, а остальные скрыты. Мне нужно, чтобы он по-прежнему отображал все листы, которые показывались. Вторая проблема — это лист «Табель рабочего времени» и два скрытых листа, которые используются для данных и настроек, которые включаются в электронное письмо. Хорошо, что все листы, которые мне нужно исключить, имеют фиксированные имена. Итак, вы можете добавить какой-то дополнительный код, исключающий листы по имени?

TacoSteve 24.05.2019 02:53

Это сработало прекрасно! Огромное спасибо. Последнее, что я сделал, это взял часть своего исходного кода, который объединяет всю электронную таблицу в один PDF-файл, и добавил его к вашему (мне нужен как пакет, так и отдельные отправленные PDF-файлы). Вот что я добавил: var ssa = SpreadsheetApp.getActiveSpreadsheet(); var blob = DriveApp.getFileById(ssa.getId()).getAs("application/pdf"); blob.setName('name of file'); затем я изменил {attachments:fA} на {attachments:[fA, blob]}, но получил ошибку Недопустимый аргумент: вложения. Как отправить оба вложения по электронной почте?

TacoSteve 24.05.2019 04:29

Проблема в том, что вложения описываются как массив файлов, а не BLOB-объектов. Я думаю, что достаточно просто показать все листы, кроме исключений, и нажать на fA.

Cooper 24.05.2019 04:51

О, это гораздо лучший способ сделать это. Все так хорошо работает! Большое спасибо за помощь, а также за оптимизацию исходного кода. Я многому научился, пройдя через это.

TacoSteve 24.05.2019 22:44

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