简体   繁体   English

从 Google Apps 脚本 doGet(e) 返回两个值

[英]Return two values from Google Apps Script doGet(e)

I am trying to create a custom pdf web app on Google Apps Script, replacing values into my template Google Document.我正在尝试在 Google Apps 脚本上创建自定义 pdf web 应用程序,将值替换到我的模板 Google 文档中。 I generate numbers in the numGenerator function, and I want to return these numbers too for later use in my python file.我在 numGenerator function 中生成数字,我也想返回这些数字以供以后在我的 python 文件中使用。

function numGenerator(digits){
   let listOfNums = [];
   const powerOfTen = Math.pow(10, digits);
   
   //Addition
   for (i=0; i<6; i++) {
     let num = getRandomNumber(0, powerOfTen);
     sendToList(num, listOfNums);
   }
   //Subtraction
   for (i=6; i<14; i+=2) {
     let num1 = getRandomNumber(0, powerOfTen);
     let num2 = getRandomNumber(num1, powerOfTen);
     sendToList(num2, listOfNums);
     sendToList(num1, listOfNums);
   }
   //Multiplication
   for (i=14; i<22; i+=2) {
     let num1 = getRandomNumber(2, (powerOfTen/10));
     let num2 = getRandomNumber(2, 20);
     sendToList(num1, listOfNums);
     sendToList(num2, listOfNums);
   }
   //Division
   for (i=22; i<30; i+=2) {
     let num2 = getRandomNumber(2, (powerOfTen/10));
     let num1 = getRandomNumber(2, (num2/10));     
     sendToList(num1*num2, listOfNums);
     sendToList(num2, listOfNums);
   }
   return listOfNums;
 }

function createDocument(doc_id, digits) {
  const listOfNums = numGenerator(digits)
  var TEMPLATE_ID = '#########';  // Google Doc template
  var documentId = DriveApp.getFileById(TEMPLATE_ID).makeCopy().getId();
  
  drivedoc = DriveApp.getFileById(documentId);
  drivedoc.setName("Mental Math Starter Exercise" + doc_id); // Copy created
  
  doc = DocumentApp.openById(documentId);
  
  var body = doc.getBody();
  
  body.replaceText('<ID>', doc_id);
  body.replaceText('<digits>', digits)
  
  for (i=1; i<=30; i++){
    body.replaceText('<num' + i + '>', listOfNums[i-1])  // Generated numbers inserted
  }
  
  drivedoc.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);

  return [listOfNums, "https://docs.google.com/document/d/" + documentId + "/export?format=pdf"]; // This might be a problem
}

function doGet(e) {
  var invoice_id = e.parameter.invoice_id; // fetches parameters
  var digits = e.parameter.digits // fetches parameters
  var url = createDocument(invoice_id, digits); // url should be a list here
  return (url[0], ContentService.createTextOutput(url[1])); //Should have returned the listOfNums and the document here
}

Before I tried to return two values from the function, the following Python code worked fine, downloading the custom worksheet.在我尝试从 function 返回两个值之前,以下 Python 代码运行良好,下载了自定义工作表。

import requests
import random
from PyPDF2 import PdfFileMerger
import os

url = "https://script.google.com/macros/s/AKfycbyWXUQkpxyxDtj8lsOZtdaCBqRJUMZ1f9jXOFaTN82HtGIMIFc/exec?invoice_id={" \
      "}&digits={}"

def createPDF(digits):

    merger = PdfFileMerger()

    for digit in digits:
        id_num = random.randint(0, 10000)
        print("processing ", id_num, digit)
        docURL = requests.get(url.format(id_num, digit))
        print("file generated")
        document = requests.get(docURL.content)
        print("file downloaded")
        listOfNums = document.content[0]
        with open("worksheet{}.pdf".format(id_num), "wb") as f:
            f.write(document.content[1])
            # merger.append(response.content)
        merger.append("worksheet{}.pdf".format(id_num))
        os.remove("worksheet{}.pdf".format(id_num))

    merger.write("result.pdf")
    merger.close()
    print("Worksheet bundle downloaded")

However, now that I'm trying to access both the document and the listOfNums, I get the following error:但是,现在我正在尝试访问文档和 listOfNums,我收到以下错误:

  File "/Users/vkhanna/PycharmProjects/MachineLearning/pdfRequest.py", line 22, in createPDF
    f.write(document.content[1])
TypeError: a bytes-like object is required, not 'int'

How can I successfully return both the listOfNums and the document?如何成功返回 listOfNums 和文档? I know I'm missing something simple.我知道我错过了一些简单的东西。

Part 1. Python第 1 部分。 Python

You should be careful with the public contract of your functions, especially when developing in multiple languages.你应该小心你的函数的公共契约,尤其是在使用多种语言开发时。 Let us go step by step and see why the error happens.让我们一步一步 go 看看为什么会发生错误。

First, the Response object has a content property, which is the "content of the response, in bytes" , so far so good.首先,响应 object 有一个content属性,即“响应的内容,以字节为单位” ,到目前为止一切顺利。 Next, the write method accepts "either to a string (in text mode) or a bytes object (in binary mode)" .接下来, write方法接受“字符串(文本模式)或字节 object(二进制模式)” Finally, trying to read the value by index from bytes data type results in int (as a byte is an integer).最后,尝试从bytes数据类型中按索引读取值会导致int (因为字节是整数)。

All the above result in the error you get.以上所有导致您得到的错误。 write expected bytes or str , but got an int . write预期的bytesstr ,但得到一个int You could use a json method or a text property of the Response instead to work directly on JSON data, the exact implementation is up to you.您可以使用json方法或响应text属性来直接处理 JSON 数据,具体实现取决于您。


Part 2. Google Apps Script第 2 部分。Google Apps 脚本

Even if you fix the client, there are still problems with your Web App.即使您修复了客户端,您的 Web App 仍然存在问题。 First, you cannot return multiple values from a function in JavaScript.首先,您不能从 JavaScript 中的 function 返回多个值 Although, as mentioned, the comma operator 's behaviour may trick you into thinking that this is allowed.尽管如前所述, 逗号操作符的行为可能会诱使您认为这是允许的。 The problem is that only the last argument will be returned, to demonstrate:问题是只会返回最后一个参数,以演示:

 const test = () => { const u = 1, l = 2; return u, l; }; console.log(test());

Secondly, you should either return a TextOutput or an HtmlOutput from a doGet or doPost trigger function to get a correct response back (your response was correct by accident).其次,您应该从doGetdoPost触发器 function 返回一个TextOutput或一个HtmlOutput以获得正确的响应(您的响应是偶然正确的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 google apps脚本doGet - google apps script doGet Google Apps 脚本:无法将 URL 参数从 doGet() 传递到 doPost() - Google Apps Script: Trouble Passing URL Params from doGet() to doPost() 每次发送包含 Web 应用程序的嵌入式链接的草稿时,如何阻止请求发送到 doGet(e)? (Google Apps 脚本) - How to stop a request from going out to doGet(e) every time a draft containing embedded link to web app is SENT? (Google Apps Script) 应用程序脚本 doGet 返回的日期与工作表上的日期不同 - Apps script doGet return not the same date as on sheet Google Apps Script onFormSubmit(e)“e 未定义”? - Google Apps Script onFormSubmit(e) "e is undefined"? 如何在 Google Apps 脚本中的二维数组 map 中从一行返回两行 - How to return two rows from one during a 2D array map in Google Apps Script 使用Google Apps脚本返回多次出现的值 - Return the values that occurred multiple times using google apps script Google Apps脚本返回数组值,并在javascript函数中使用它们 - Google Apps Script return array values and use them in a javascript function Google Apps脚本返回正确的值+多个不需要的逗号 - Google apps script return correct values + multiple not required commas Google Apps Script 中的多页站点:如何通过 jquery 或 javascript 调用 doGet()? - Multi-page site in Google Apps Script: How to invoke doGet() through jquery or javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM