在Gscript中,如何在不超时的情况下将工作表转换为多个pdf

时间:2019-04-14 03:06:14

标签: pdf google-apps-script google-sheets-api

我正在尝试设置一本成绩簿,我想遍历一张具有各种vlookups的工作表中的学生列表,以创建一个单独的成绩单。然后,我想为每个学生制作一个pdf文件。在大约有6个学生之后,我一直在服务器请求上遇到超时问题。错误消息报告“返回的代码429”。

我以为我可以使用它,但是它将为每个学生创建一个pdf文件,其中包含第一个学生的信息和姓名。我尝试了在互联网上找到的各种代码段,但由于请求数量过多,这些代码段也会超时。

    function PrintReport() {
    SpreadsheetApp.getActiveSpreadsheet().toast('Writing the reports.','Printing Reports');

        var email = Session.getActiveUser().getEmail();
        var TodayDate = new Date();
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var ClassName = ss.getName()
        var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
        var StudentList = ss.getSheetByName('Mark Sheet');
        var StudentCount = StudentList.getRange("A2").getValue();
        var SLData = StudentList.getRange(7,1,StudentCount).getValues();
        var ReportSheet = ss.getSheetByName('Student Report');
        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
            + '&fitw=true&source=labnol'           // fit to page width, false for actual size
            + '&sheetnames=False&printtitle=True' // 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 blobs = [];
      var sheetID = ss.getSheetByName('Student Report').getSheetId();
      var url_base = ss.getUrl().replace(/edit/,'');


    for (var i = 0; i < StudentCount; i++){
          ReportSheet.setActiveSelection("B1").setValue(SLData[i][0].toString());
          SpreadsheetApp.flush();


            var response = UrlFetchApp.fetch(url + url_ext + sheetID, {
              headers: {'Authorization': 'Bearer ' +  token
          }
        });
          //convert the response to a blob and store in our array
          blobs[i] = response.getBlob().setName(SLData[i][0] + '.pdf');

      }

    ReportSheet.setActiveSelection("B1").setValue(SLData[0][0]);
    //create new blob that is a zip file containing our blob array
      var zipBlob = Utilities.zip(blobs).setName(ClassName+': Student Reports'+'.zip');

      var subject = ClassName+ ": Individual Reports";
      var body = "How to print multiple files: Just select all the items you wish to print in Finder and tap Command-P (or choose File>Print). If your system can print those items, it will.";

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

    SpreadsheetApp.getActiveSpreadsheet().toast('Reports are all done, please check you email.','Reports',5);

}

应该使用学生姓名创建一个pdf压缩文件。下载并解压缩zip时,pdf包含每个学生的分数细分。

如果我将“响应”代码移到循环外,则会生成仅包含一个学生数据的多个PDF。

更新 修改为以下代码,但现在为每个学生制作了一个pdf文件,但每个人都有最后一个学生的信息(标记和姓名)。

function PrintReport() {
SpreadsheetApp.getActiveSpreadsheet().toast('Writing the reports.','Printing Reports');

    var email = Session.getActiveUser().getEmail();
    var TodayDate = new Date();
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var ClassName = ss.getName();
    var StudentList = ss.getSheetByName('Mark Sheet');
    var StudentCount = StudentList.getRange("A2").getValue();
    var SLData = StudentList.getRange(7,1,StudentCount).getValues();
    var ReportSheet = ss.getSheetByName('Student Report');
    var sheetID = ss.getSheetByName('Student Report').getSheetId();
    var blobs = [];

hideAllSheetsExcept('Student Report');

for (var i = 0; i < StudentCount; i++){
      ReportSheet.setActiveSelection("B1").setValue(SLData[i][0].toString());
      SpreadsheetApp.flush();
      //convert the response to a blob and store in array
      blobs.push(ss.getBlob().getAs('application/pdf').setName(SLData[i][0] + '.pdf'));
      //creates a pdf of the last student's information for everyone!
    }

ReportSheet.setActiveSelection("B1").setValue(SLData[0][0]);
//create new blob that is a zip file containing our blob array
  var zipBlob = Utilities.zip(blobs).setName(ClassName+': Student Reports'+'.zip');

  var subject = ClassName+ ": Individual Reports";
  var body = "How to print multiple files: Just select all the items you wish to print in Finder and tap Command-P (or choose File>Print). If your system can print those items, it will.";

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

SpreadsheetApp.getActiveSpreadsheet().toast('Reports are all done, please check you email.','Reports',5);
UnHideEverything();
}

1 个答案:

答案 0 :(得分:1)

  1. 我在while循环和超时中添加了一个try catch。完美运行

  2. 这样嵌套您的响应:

     var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/'  
     + ssID  
     + '/export?exportFormat=pdf&format=pdf'
     + '&size=A4'
     + '&portrait=true'
     + '&fitw=true'       
     + '&top_margin=0.50'              
     + '&bottom_margin=0.50'          
     + '&left_margin=0.50'             
     + '&right_margin=0.50'           
     + '&sheetnames=false&printtitle=false'
     + '&pagenum=false'
     + '&gridlines=false'
     + '&fzr=FALSE'      
     + '&gid='
     + GID;
    
    var response
    var done = false
    while (!done){
      try{
        response = UrlFetchApp.fetch(theurl, params)
        done = true
      } catch (e) {
        console.log(e)
        done = false
        Utilities.sleep(10000)
      }
    }