PDF 附件损坏

PDF attachment corrupted

在 GmailApp 声明问题得到解决后,我现在遇到了一个新问题,关于我的 pdf 附件无法读取。

在此之前 ,pdf 附件运行良好。

我怀疑 var“blobresponse”或“pdfOpts”是问题的根源,但也许我错了。

脚本出了什么问题?你能解释一下吗? 这是一个可重现的 example

function emailAsPDF() {

 SpreadsheetApp.flush();
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 ss.setActiveSheet(ss.getSheetByName("Recherche"));
 var sheet = ss.getActiveSheet();
 var gid = sheet.getSheetId();
 var pdfOpts = 
    'exportFormat=pdf&format=pdf'+ // export as pdf
    '&size=0' + // paper size letter / You can use A4 or legal
    '&portrait=false' + // orientation portal, use false for landscape
    '&fitw=true' + // fit to page width false, to get the actual size
    '&sheetnames=false&printtitle=true' + // hide optional headers and footers
    '&pagenumbers=true&gridlines=false' + // hide page numbers and gridlines
    '&horizontal_alignment=CENTER&vertical_alignment=CENTER' +
    '&fzr=true' + // do not repeat row headers (frozen rows) on each page
    '&attachment=false' +
    gid;
// '&size=0&fzr=true&portrait=false&fitw=true&gridlines=false&printtitle=true&sheetnames=false&pagenumbers=true&attachment=false&gid='+gid;
 
 
 SourceSS = SpreadsheetApp.getActive();
 var SourceSheet = SourceSS.getSheetByName("Recherche");
 var url = 'https://docs.google.com/spreadsheets/d/' + SourceSS.getId().replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;
 //var url = 'https://docs.google.com/spreadsheets/d/'.replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;
 var token = ScriptApp.getOAuthToken();
 //var options = {
      
//options = {muteHttpExceptions: true};
 //var options = {
  var blobresponse = UrlFetchApp.fetch(url, {
    headers: {
        'Authorization': 'Bearer ' +  token,
      },
      muteHttpExceptions: true}
    );
  //options);
  var CandidateName = ss.getRangeByName("Nom.Candidat").getValue();
  var blob=blobresponse.getBlob().setName(ss.getName() + " - " + CandidateName +".pdf" );
  var emailAddress = Session.getActiveUser().getEmail();
  var signature = Gmail.Users.Settings.SendAs.get("me", emailAddress).signature; 
  var mess = "Voulez-vous envoyer votre rapport  à l'adresse : " + emailAddress;
  var ans= Browser.msgBox("Courriel", mess, Browser.Buttons.YES_NO);
  if (ans===Browser.Buttons.NO){return;}
  var mess="Votre rapport a été envoyé à l'adresse : " + emailAddress;
  //var ss=SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Recherche");
  var data = ss.getSheetByName("Données");
  const corps = data.getRange("A24:E27").getValues();
  const htmlTemplate = HtmlService.createTemplateFromFile("HtmlSigTemplate");
  htmlTemplate.corps = corps;
  var emailSubject = "Vérifications pré-emploi complétées" +" - "+ CandidateName;
  const htmlForEmail = htmlTemplate.evaluate().getContent() + "--" + "<br>" + signature;
  //console.log(htmlForEmail);
  GmailApp.sendEmail(
    emailAddress, 
    emailSubject, 
    corps,
    {htmlBody: htmlForEmail,
    attachments:[blob]});
  Browser.msgBox("Courriel", mess, Browser.Buttons.OK); 
}


function parentFolder() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var file = DriveApp.getFileById(ss.getId()); 
  var ParentFolder= file.getParents();
  while ( ParentFolder.hasNext() ) {
    var folder = ParentFolder.next();
    folderID=folder.getId();
     Logger.log(folderID);
  }
  return folderID;
}

代码有几个问题。我建议您通过删除冗余语句并采用更好的现代 JavaScript 实践来开始清理您的脚本。即

而不是 var 使用 constlet。旧 Google Apps 脚本代码一直使用 var,因为 constlet 不受支持。当前 Google Apps 脚本默认运行时执行此操作。

相关

  • What's the difference between using "let" and "var"?

而不是

ss.setActiveSheet(ss.getSheetByName("Recherche"));
 var sheet = ss.getActiveSheet(); 

使用

 const sheet = ss.getSheetByName("Recherche");

而不是

SourceSS = SpreadsheetApp.getActive();
 var SourceSheet = SourceSS.getSheetByName("Recherche");
 var url = 'https://docs.google.com/spreadsheets/d/' + SourceSS.getId().replace(/edit$/, '') + '/export?exportformat=pdf&format=pdf' + pdfOpts;

使用

const url = 'https://docs.google.com/spreadsheets/d/' + ss.getId() + '/export?exportformat=pdf&format=pdf' + pdfOpts;

备注:

  1. getId() returns spreadsheet id,它不包括 edit.
  2. 无需为要导出为 PDF 的传播sheet 和 sheet 声明新变量,因为之前声明的变量具有所需的对象。

此外,您可能会发现回顾以前与使用 UrlFetchApp 创建 PDF 相关的问题会有所帮助,如下所示:

  • Exporting Google Sheet as PDF with Custom Headers or Footers in Google Apps Script

经过漫长而痛苦的研究,我找到了罪魁祸首。您注意到变量 pdfOpts 的最后一行缺少一些细节

旧代码:

var pdfOpts = 
    'exportFormat=pdf&format=pdf'+ // export as pdf
    '&size=0' + // paper size letter / You can use A4 or legal
    '&portrait=false' + // orientation portal, use false for landscape
    '&fitw=true' + // fit to page width false, to get the actual size
    '&sheetnames=false&printtitle=true' + // hide optional headers and footers
    '&pagenumbers=true&gridlines=false' + // hide page numbers and gridlines
    '&horizontal_alignment=CENTER&vertical_alignment=CENTER' +
    '&fzr=true' + // do not repeat row headers (frozen rows) on each page
    '&attachment=false' +
    gid;

新代码:

  const pdfOpts = '&top_margin=0.30&bottom_margin=0.30&left_margin=0.25&right_margin=0.25'
    +'&size=LETTER' // paper size letter / You can use A4 or legal
    +'&portrait=false' // orientation portal, use false for landscape
    +'&fitw=true' // fit to page width false, to get the actual size
    +'&sheetnames=false' // hide optional headers
    +'&printtitle=true' //and footers
    +'&pagenumbers=true' // hide page numbers 
    +'&gridlines=false' //and gridlines
    +'&horizontal_alignment=CENTER'
    +'&vertical_alignment=CENTER'
    +'&fzr=true' // do not repeat row headers (frozen rows) on each page
    +'&attachment=false'
    +'&gid='+gid;