У меня есть электронная таблица, в которой всегда есть лист с именем «Табель рабочего времени», и человек, который его заполняет, может создать столько дополнительных листов заметок, сколько ему нужно.
Мне нужно, чтобы все листы, кроме листа «Табель рабочего времени», были преобразованы в отдельные 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-файл, мне нужно, чтобы каждый лист был отдельным PDF-файлом.
Я собираюсь поработать над этим сегодня утром, потому что я хочу знать, как это сделать.
Отправка листов электронной таблицы по электронной почте в виде отдельных 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);
}
}
Вау, спасибо, что так внимательно изучили это, я проверю это сегодня вечером, когда вернусь домой. И да, в моем коде могли быть какие-то странные вещи, я не разработчик, поэтому это куча кода, который я нашел в Интернете и сшил вместе. Спасибо еще раз!
Так что до сих пор он работает хорошо, он отправляет мне все PDF-файлы как отдельные лица. Есть две небольшие проблемы, которые я не думаю, что будут серьезные исправления. Во-первых, когда он перебирает все листы, он скрывает остальные. В конце отображается последний лист, а остальные скрыты. Мне нужно, чтобы он по-прежнему отображал все листы, которые показывались. Вторая проблема — это лист «Табель рабочего времени» и два скрытых листа, которые используются для данных и настроек, которые включаются в электронное письмо. Хорошо, что все листы, которые мне нужно исключить, имеют фиксированные имена. Итак, вы можете добавить какой-то дополнительный код, исключающий листы по имени?
Это сработало прекрасно! Огромное спасибо. Последнее, что я сделал, это взял часть своего исходного кода, который объединяет всю электронную таблицу в один 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]}
, но получил ошибку Недопустимый аргумент: вложения. Как отправить оба вложения по электронной почте?
Проблема в том, что вложения описываются как массив файлов, а не BLOB-объектов. Я думаю, что достаточно просто показать все листы, кроме исключений, и нажать на fA.
О, это гораздо лучший способ сделать это. Все так хорошо работает! Большое спасибо за помощь, а также за оптимизацию исходного кода. Я многому научился, пройдя через это.
Просто скройте все листы, которые вам не нужны в pdf.