尝试在 Sheets Javascript 中通过电子邮件发送多个 PDF Blob

问题描述 投票:0回答:1

我想要的是:一个可以生成 pdf 的 Google 表格,将 PDF 保存到您的 GDrive,然后向您发送一封附有所有 pdf 的电子邮件。

我能做的:

  • 生成 PDF
  • 将 PDF 保存到 GDrive
  • 通过电子邮件发送个人 PDF

我的(恶心的爱好者)代码循环创建pdf文件很好,但是当我尝试将它们保存/推送到数组时,或者当我尝试将数组附加到电子邮件时,它就会挂起。

(可能)有问题的代码行已用一行

指出

========================================s

  // ======================================== //
  //                                          //
  //      GENERATE MULTIPLE LOGS AT ONCE      //
  //                                          //
  // ======================================== //

function printMultiple() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();

  var lastRow = ss.getRange("AN:AN").getValues().filter(String).length;
  var targetRange = ss.getSheetByName("Show 3 Mileage Form").getRange(1,40,lastRow,1);
  var workerList = String(targetRange.getValues()).replaceAll(", ","+++").split(",");

  var printAllBox = ui.alert("PRINT ALL MILEAGE LOGS", "Attempting to generate pdfs for everybody who drove this week.\n\nThis might take a while, so don't touch anything.",ui.ButtonSet.OK_CANCEL);

    if (printAllBox === ui.Button.OK) {

      var timer = 0;
      var counter = 0;

      for (var i = 0; i < workerList.length; i++) {
        workerList[i] = workerList[i].replaceAll("+++",", ");
        ss.getRange("E2").setValue(workerList[i]);
    
        if (ss.getRange("PRINT!I10").getValue() == ""){  }

        else {
                    
          var sheet;
          var email = Session.getEffectiveUser().getEmail();
          var subject = "Multiple Mileage Logs";
          var body = "Mileage logs generated."

          // Look to see if it's a two pager or not

          if (ss.getRange("PRINT!G1").getValue() == "PAGE 1 of 1") { sheet = ss.getSheetByName("PRINT");}
          else { sheet = ss.getSheetByName("PRINT - 2 PAGE"); }

          // show the print sheet
          sheet.showSheet();

          const fileName = ss.getRange("PRINT!J2").getValue()+".pdf";
                  
          // Base URL
          var exportURL = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());

          var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
          + '&size=letter'                            // paper size legal / letter / A4
          + '&portrait=false'                         // orientation, false for landscape
          + '&fith=true&'                             // fit to page width, false for actual size  CHANGED TO HEIGHT
          + "&gridlines=false" 
          + "&top_margin=0.25" 
          + "&bottom_margin=0.25" 
          + "&left_margin=0.5" 
          + "&right_margin=0.5" 
          + '&sheetnames=false&printtitle=false'      // hide optional headers and footers
          + '&pagenumbers=false&gridlines=false'      // hide page numbers and gridlines
          + '&fzr=false'                              // do not repeat row headers (frozen rows) on each page
          + '&gid=';                                  // the sheet's Id

          var token = ScriptApp.getOAuthToken();

          //make an empty array to hold your fetched blobs  
          var pdf;
          var pdfCluster = [];

          // Convert your specific sheet to blob
          var response = UrlFetchApp.fetch(exportURL + url_ext + sheet.getSheetId(), {
          headers: { 'Authorization': 'Bearer ' +  token }
          });

          //  And then hide the printsheet
          sheet.hideSheet();

          //convert the response to a blob and store in our array
          pdf = response.getBlob().setName(fileName);

// =======================================================================================

          // I originally tried using the variable "pdf" as the array 
          // and figured that maybe having a completely separate 
          // variable might help

          pdfCluster.push(pdf);

          // I also tried going the pdfCluster[i] = pdf route 

// =======================================================================================

          // Check to see if they have the right folders in place, and if not, create them
          var folder1 = "gripPDFs"                          //  gripPDFs
          var folder2 = ss.getRange("PRINT!C5").getValue()  //  Job Name
          var folder3 = "mileage logs"                      //  mileage logs  
          var folder4 = ss.getRange("PRINT!K2").getValue()  //  date

          /* Find the first level folder, create if the folder does not exist */
          var folders = DriveApp.getFoldersByName(folder1);
          var firstLevelFolder = (folders.hasNext()) ? folders.next() : DriveApp.createFolder(folder1);
                                        
          /* Layer2 */
          folders = DriveApp.getFoldersByName(folder2);
          var secondlevelFolder = (folders.hasNext()) ? folders.next() : firstLevelFolder.createFolder(folder2); 

          /* Layer3 */
          folders = DriveApp.getFoldersByName(folder3);
          var thirdlevelFolder = (folders.hasNext()) ? folders.next() : secondlevelFolder.createFolder(folder3); 

          /* Layer4 */
          folders = DriveApp.getFoldersByName(folder4);
          var finalfolder = (folders.hasNext()) ? folders.next() : thirdlevelFolder.createFolder(folder4); 

          // And create that shit
          finalfolder.createFile(pdf);

          counter = (counter + 1);
          timer = timer + 1;
          if (timer > 3) { 
            // Sleep to appease the Google Lag Police
            SpreadsheetApp.flush();
            Utilities.sleep(5000);
            SpreadsheetApp.flush();
            timer = 0;
          }
        }
      }

  //And mail it!
  GmailApp.sendEmail(email, subject, body, {

// =======================================================================================

  attachments: [pdfCluster]

// =======================================================================================

  });

  var pdfResults = ui.alert("PROCESS COMPLETE",counter +" total logs printed.  The files have been emailed to you and can be found under "+folder1+"/"+folder2+"/"+folder3+"/"+folder4+" in your Google Drive.",ui.ButtonSet.OK);



  }
}


javascript email google-sheets pdf blob
1个回答
0
投票

问题在于您如何处理 pdf 数组和附件。尝试下面的代码,看看是否可以解决问题:

function printMultiple() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();

  var lastRow = ss.getRange("AN:AN").getValues().filter(String).length;
  var targetRange = ss.getSheetByName("Show 3 Mileage Form").getRange(1,40,lastRow,1);
  var workerList = String(targetRange.getValues()).replaceAll(", ","+++").split(",");

  var printAllBox = ui.alert("PRINT ALL MILEAGE LOGS", "Attempting to generate pdfs for everybody who drove this week.\n\nThis might take a while, so don't touch anything.",ui.ButtonSet.OK_CANCEL);

  if (printAllBox === ui.Button.OK) {
    var timer = 0;
    var counter = 0;
    // Initialize the array outside the loop
    var pdfBlobs = [];

    for (var i = 0; i < workerList.length; i++) {
      workerList[i] = workerList[i].replaceAll("+++",", ");
      ss.getRange("E2").setValue(workerList[i]);
  
      if (ss.getRange("PRINT!I10").getValue() == "") {
        continue;  // Skip empty entries
      }
              
      var sheet;
      var email = Session.getEffectiveUser().getEmail();
      var subject = "Multiple Mileage Logs";
      var body = "Mileage logs generated."

      // Look to see if it's a two pager or not
      if (ss.getRange("PRINT!G1").getValue() == "PAGE 1 of 1") {
        sheet = ss.getSheetByName("PRINT");
      } else {
        sheet = ss.getSheetByName("PRINT - 2 PAGE");
      }

      // show the print sheet
      sheet.showSheet();

      const fileName = ss.getRange("PRINT!J2").getValue() + ".pdf";
              
      // Base URL
      var exportURL = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());

      var url_ext = 'exportFormat=pdf&format=pdf'
        + '&size=letter'
        + '&portrait=false'
        + '&fith=true&'
        + "&gridlines=false" 
        + "&top_margin=0.25" 
        + "&bottom_margin=0.25" 
        + "&left_margin=0.5" 
        + "&right_margin=0.5" 
        + '&sheetnames=false&printtitle=false'
        + '&pagenumbers=false&gridlines=false'
        + '&fzr=false'
        + '&gid=';

      var token = ScriptApp.getOAuthToken();

      // Convert your specific sheet to blob
      var response = UrlFetchApp.fetch(exportURL + url_ext + sheet.getSheetId(), {
        headers: { 'Authorization': 'Bearer ' + token }
      });

      //  And then hide the printsheet
      sheet.hideSheet();

      // Convert the response to a blob and store in our array
      var pdf = response.getBlob().setName(fileName);
      // Add the PDF blob to our array
      pdfBlobs.push(pdf);

      // Check to see if they have the right folders in place, and if not, create them
      var folder1 = "gripPDFs"
      var folder2 = ss.getRange("PRINT!C5").getValue()
      var folder3 = "mileage logs"
      var folder4 = ss.getRange("PRINT!K2").getValue()

      /* Find the first level folder, create if the folder does not exist */
      var folders = DriveApp.getFoldersByName(folder1);
      var firstLevelFolder = (folders.hasNext()) ? folders.next() : DriveApp.createFolder(folder1);
                                    
      /* Layer2 */
      folders = DriveApp.getFoldersByName(folder2);
      var secondlevelFolder = (folders.hasNext()) ? folders.next() : firstLevelFolder.createFolder(folder2); 

      /* Layer3 */
      folders = DriveApp.getFoldersByName(folder3);
      var thirdlevelFolder = (folders.hasNext()) ? folders.next() : secondlevelFolder.createFolder(folder3); 

      /* Layer4 */
      folders = DriveApp.getFoldersByName(folder4);
      var finalfolder = (folders.hasNext()) ? folders.next() : thirdlevelFolder.createFolder(folder4); 

      // Save to Drive
      finalfolder.createFile(pdf);

      counter = (counter + 1);
      timer = timer + 1;
      if (timer > 3) { 
        // Sleep to appease the Google Lag Police
        SpreadsheetApp.flush();
        Utilities.sleep(5000);
        SpreadsheetApp.flush();
        timer = 0;
      }
    }

    // Send email with all PDFs attached
    GmailApp.sendEmail(email, subject, body, {
      attachments: pdfBlobs  // Pass the array of blobs directly
    });

    var pdfResults = ui.alert("PROCESS COMPLETE", 
      counter + " total logs printed. The files have been emailed to you and can be found under " +
      folder1 + "/" + folder2 + "/" + folder3 + "/" + folder4 + " in your Google Drive.",
      ui.ButtonSet.OK);
  }
}

我将

pdfBlobs
数组初始化移到循环之外。 还使用
pdfBlobs.push(pdf)
将每个 pdf blob 推送到数组,并在将附件数组传递到
GmailApp.sendEmail()
时删除方括号。 我添加了一个 continue 语句来跳过空条目并清理了一些代码格式结构。

问题是您每次通过循环创建一个新数组,并且还尝试附加包装在另一个数组中的数组

([pdfCluster])

代码现在要做的是:

  • 创建所有 pdf
  • 将它们存储在一个数组中
  • 保存它们来开车
  • 发送一封附有所有 pdf 的电子邮件。

尝试一下,看看是否有效。

© www.soinside.com 2019 - 2024. All rights reserved.