You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Sheets JavaScript批量生成PDF并统一邮件发送问题求助

Google Sheets JavaScript批量生成PDF并统一邮件发送问题求助

各位好,我目前在开发Google Sheets的脚本,想实现以下功能:

  • 批量生成PDF文件
  • 将这些PDF保存到Google Drive
  • 发送单封邮件,把所有生成的PDF作为附件一起发送

目前我已经能做到这些:

  • 生成单个PDF文件
  • 把PDF保存到Google Drive
  • 给每个PDF单独发送邮件

但现在遇到了麻烦:循环生成PDF的逻辑是正常的,但要么在把PDF存入数组时出问题,要么在尝试把数组作为附件添加到邮件时卡住。我把可能出问题的代码段用分割线标出来了,麻烦大家帮忙看看哪里出错了!

下面是我的完整代码:

// ======================================== //
  //                                          //
  //      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;
      // 👇 把数组声明移到循环外面!原来放在循环里每次都会重置为空数组
      var pdfCluster = [];

      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();
          var pdf;

          // 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);

// =======================================================================================
          // 我原本尝试直接用pdf作为数组,后来想着单独用一个数组变量可能有用,就改成了pdfCluster
          // 我试过push方法,也试过直接赋值pdfCluster[i] = pdf,但都没成功
          pdfCluster.push(pdf);
// =======================================================================================

          // 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);

  }
}

我自己排查时发现可能的问题点:

  1. 原来把pdfCluster数组声明放在了循环内部,导致每次循环都会重置数组,现在我移到了循环外面,但还是不确定是不是这个原因
  2. 邮件附件的参数attachments应该直接传数组,而不是把数组再包一层数组

麻烦各位帮忙排查一下问题,谢谢大家!

备注:内容来源于stack exchange,提问作者Yoko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 18:27:57