Google apps script 在表单提交时生成PDF

Google apps script 在表单提交时生成PDF,google-apps-script,Google Apps Script,嗨,我是新来的论坛和编程谷歌脚本。我是一名技术教师,我正在努力为我的学生开发一个课程跟踪软件。我一直在看视频,试图得到一个表格,自动生成一个PDF,然后通过电子邮件发送给我的学生和他们的父母。我正处于知识匮乏的阶段。我能够让createpdf函数自己工作,但是在表单提交触发后,我无法让我的代码生成PDF。运行afterFormSubmit函数时,出现以下错误:TypeError:无法读取未定义的属性“namedValues”。这是我的代码和错误报告-如果能得到任何帮助,我将不胜感激。提前谢谢 f

嗨,我是新来的论坛和编程谷歌脚本。我是一名技术教师,我正在努力为我的学生开发一个课程跟踪软件。我一直在看视频,试图得到一个表格,自动生成一个PDF,然后通过电子邮件发送给我的学生和他们的父母。我正处于知识匮乏的阶段。我能够让createpdf函数自己工作,但是在表单提交触发后,我无法让我的代码生成PDF。运行afterFormSubmit函数时,出现以下错误:TypeError:无法读取未定义的属性“namedValues”。这是我的代码和错误报告-如果能得到任何帮助,我将不胜感激。提前谢谢

function afterFormSubmit(e) {
  const info = e.namedValues;
  createPDF(info);
}


function createPDF(info){

  const pdfFolder=DriveApp.getFolderById("1jbXL5laCExwwrycDTIearbnXXwwQIms0");
  const tempFolder = DriveApp.getFolderById("16r7H5gZAxbwdE_6vWUTUwpOVX8_Cw3oX");
  const templateDoc= DriveApp.getFileById("12qrcjOPVJxuThJVyLARBKcCatkwVNO865lGheUbdDdk");
  
  const newTempFile = templateDoc.makeCopy(tempFolder);

  const openDoc =  DocumentApp.openById(newTempFile.getId());
  const body = openDoc.getBody();
  
  body.replaceText("{SEmail}", info['Email Address'][0]);
  body.replaceText("{FName}", info['First Name'][0]);
  body.replaceText("{LName}", info['Last Name'][0]);
  body.replaceText("{PEmail}", info['Parents Preferred Email Address'][0]);
  body.replaceText("{VersionDate}", info['Timestamp'][0]);
  body.replaceText("{GradDate}", info['What year are you scheduled to graduate from Shaker High School?'][0]);
  body.replaceText("{PSequence}", info['What is your preferred Tech Sequence?'][0]);
  body.replaceText("{DDE}", info['Have you taken course 811 - Design and Drawing for Engineering?'][0]);
  body.replaceText("{POE}", info['Have you taken course 812 - Principles of Engineering?'][0]);
  body.replaceText("{WOODS}", info['Have you taken course 850 - Wood Construction?'][0]);
  body.replaceText("{CAP}", info['Have you taken course 817 - Engineering Capstone?'][0]);
  body.replaceText("{ER}", info['Have you taken course 830 - Electronics and Robotics?'][0]);
  body.replaceText("{ADR}", info['Have you taken course 834 - Advanced Robotics?'][0]);
  body.replaceText("{MPE}", info['Have you taken course 835 - Manufacturing Processes for Engineering?'][0]);
  body.replaceText("{ARCH1}", info['Have you taken course 813 - Architectural Drawing 1?'][0]);
  body.replaceText("{ARCH2}", info['Have you taken course 814 - Architectural Drawing 2?'][0]);
  body.replaceText("{HE}", info['Have you taken course 836 - Home Electricity?'][0]);
  body.replaceText("{CAD}", info['Have you taken course 838 - Computer Aided Drafting?'][0]);
  body.replaceText("{FDM}", info['Have you taken course 511 - Financial Decision Making?'][0]);
  body.replaceText("{CEIP}", info['Have you taken course 558 - Career Exploration Internship Program?'][0]);
 
openDoc.saveAndClose();

  const blobPDF=newTempFile.getAs(MimeType.PDF);
  const pdfFile = pdfFolder.createFile(blobPDF).setName(info['Last Name'][0]+" "+info['First Name'][0]);
 // tempFolder.removeFile(newTempFile);


  }

调查结果

如果您直接从应用程序脚本编辑器运行afterFormSubmit(e),这就是为什么会出现
TypeError:cannotreadproperty'namedValues'of undefined
的原因,因为
e
参数需要传递的值只有在您对表单执行实际提交操作时才会发生

我已经复制了您的脚本,并且始终得到类型
TypeError:无法读取undefined
的属性'namedValues',即使在我对表单执行实际提交操作时也是如此,因为
e.namedValues
包含空/空值

我做了一些研究来了解为什么
e.namedValues
返回空值&发现最近的一个问题报告评论说,遇到的错误很可能是由于混淆了有两个onFormSubmit触发器这一事实。一个可以绑定到电子表格,另一个可以绑定到表单

再淹没

我已经在电子表格上使用绑定脚本测试了onFormSubmit函数,电子表格上有一个创建的表单,我能够在提交表单后使
createPDF(info)
正常工作:

  • 创建一个空的电子表格文件
  • 在该电子表格文件中创建一个表单
  • 在电子表格文件中创建绑定脚本
  • 示例工作电子表格绑定脚本,可作为参考:

    function createTrigger() {
        let ss = SpreadsheetApp.getActiveSpreadsheet();
        ScriptApp.newTrigger('test')
        .forSpreadsheet(ss)
        .onFormSubmit()
        .create();
    }
    
    function test(e){
      const info = e.namedValues;
      Logger.log (info); //Log the info for review
      createPDF(info);
    }
    
    function createPDF(info){
    
      const pdfFolder=DriveApp.getFolderById("DRIVE_FOLDER_ID");
      const tempFolder = DriveApp.getFolderById("DRIVE_FOLDER_ID");
      const templateDoc= DriveApp.getFileById("DOCS_FILE_ID");
      
      const newTempFile = templateDoc.makeCopy(tempFolder);
    
      const openDoc =  DocumentApp.openById(newTempFile.getId());
      const body = openDoc.getBody();
      
      body.replaceText("{SEmail}", info['Email'][0]);
      body.replaceText("{FName}", info['Name'][0]);
    
     
    openDoc.saveAndClose();
    
      const blobPDF=newTempFile.getAs(MimeType.PDF);
      const pdfFile = pdfFolder.createFile(blobPDF).setName(info['Name'][0]);
     // tempFolder.removeFile(newTempFile);
    
      }
    
    注意:首先从编辑器运行脚本,以验证和接受所需的权限(例如DriveApp.getFolderById权限)。然后,要测试脚本,请打开表单并尝试提交

    样本表格

    样本模板文件

    结果

    以下是应用程序脚本编辑器上的执行日志

    已在驱动器文件夹上成功创建PDF文件:


    不完全是解决方案。这只是一条建议,告诉你如何找到错误的原因。您可以使用
    Logger.log()
    函数,查看您在某一点上拥有什么或您的代码。例如,当您尝试在
    replaceText()
    中使用变量
    info
    时,该变量似乎未定义。您可以尝试在代码行之间添加
    Logger.log(e)
    Logger.log(e.namedValues)
    Logger.log(info)
    Logger.log(info['Email Address])
    ,并查看它们将显示什么。您如何运行脚本?如果您从脚本编辑器运行它,它将永远不会工作。它需要打开表单,填写它,然后按提交按钮。只有这样,函数
    afterFormSubmit(e)
    才能获取非雇员对象
    e
    。如果您愿意提供事件对象,您实际上可以从脚本编辑器运行触发的脚本。您可以从中间函数调用它们,并在中间函数中创建事件对象。如果您不习惯创建对象,这可能不是您的最佳选择。但这是可能的,它提供了一种使用调试器单步执行函数的方法,这对于诊断许多问题非常有用。