如何使用从 HTML 网页传递到应用程序脚本的数据中的多个值填充 Google 表格单元格

问题描述 投票:0回答:2

我有一个 HTML 网站,提交后,它会使用我现有的应用程序脚本填充我的 Google 表格。这一切都工作正常,但我遇到的问题是在我的网站中,我有一个

table
,它允许多行,每行都有一个
input

enter image description here

这是提交后发布到我的 Google 表格的数据

Port Main Num=No&Porting Type=PRO&Range Holder=TO POPULATE&Maintain DQ=否&线路类型=多&关联号码=01111111111&关联 号码操作=端口&关联号码=02222222222&关联号码 操作=停止&相关号码=01111122222&相关号码 操作=端口&头衔=先生&首字母=t&姓氏=测试&帐户 号码=01611111111&公司名称=测试公司&建筑物名称=&地址 第 1 行=地址第 1 行&地址第 2 行=&城镇或城市=城镇&邮政编码=BB1 1BB&移植日期=08/10/2024&主要账单号码=01611111111

但是当我检查我的 Google 表格时,它只填充最后输入的数字(这是我所期望的)

enter image description here

正如你从我的数据中看到的,我传递了所有 3 个数字,所以我知道我需要一个循环,但我在网上找不到任何相关信息。我能找到的唯一帮助是在电子表格中循环单元格。

这是我当前的应用程序脚本代码

const DATA_ENTRY_SHEET_NAME = "Sheet1";
const TIME_STAMP_COLUMN_NAME = "Date";
const REF_COLUMN_NAME = "Ref";
const CUST_EMAIL_COLUMN_NAME = "Email Address";
const PORTING_TIME_COLUMN_NAME = "Porting Time";


var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(DATA_ENTRY_SHEET_NAME);

const doPost = (request = {}) => {
  const { postData: { contents, type } = {} } = request;
  var data = parseFormData(contents);
  appendToGoogleSheet(data);
  
 return ContentService.createTextOutput(contents).setMimeType(ContentService.MimeType.JSON);
};

function parseFormData(postData) {
  var data = [];
  var parameters = postData.split('&');
  for (var i = 0; i < parameters.length; i++) {
    var keyValue = parameters[i].split('=');
    data[keyValue[0]] = decodeURIComponent(keyValue[1]);
  }
  return data;
}

function appendToGoogleSheet(data) {
  if (TIME_STAMP_COLUMN_NAME !== "") {
    data[TIME_STAMP_COLUMN_NAME]=new Date();
  }

  if (sheet.getRange(sheet.getLastRow(), 2).getValue() !== 'Ref') {
    var ref = sheet.getRange(sheet.getLastRow(), 2).getValue().replace("Port-","");
    var ref = parseFloat(ref)+1
    data[REF_COLUMN_NAME]= 'Port-' + ref
  } else {
     data[REF_COLUMN_NAME]='Port-10000'
  }

  if (CUST_EMAIL_COLUMN_NAME !== "") {
    data[CUST_EMAIL_COLUMN_NAME]= '[email protected]';
  }

  if (PORTING_TIME_COLUMN_NAME !== "") {
    data[PORTING_TIME_COLUMN_NAME]= '10:00';
  }

  var headers = sheet.getRange(5, 1, 1, sheet.getLastColumn()).getValues()[0];
  var rowData = headers.map(headerFld => data[headerFld]);
  sheet.appendRow(rowData);
}
google-sheets google-apps-script google-workspace
2个回答
2
投票

问题出在你的

parseFormData
函数上。线

data[keyValue[0]] = decodeURIComponent(keyValue[1]);

keyValue[0]
属性分配一个值,如果有多个表单输入字段具有相同的
name
属性,则替换可能存在的任何先前值 - 正如您的情况。

因此,一个可能的解决方案是检查是否已经存在具有该名称的数据,在这种情况下,然后将新数据附加到该属性。这可以通过三元运算符来实现,如下所示:

data[keyValue[0]] = data[keyValue[0]] ?
  data[keyValue[0]].concat(', ', decodeURIComponent(keyValue[1])) :
  decodeURIComponent(keyValue[1]);

我的示例使用“

, 
”分隔符连接字符串。根据您想要的结果,您可以将其更改为
'\n'
或其他。

顺便问一下,您在这个函数中使用数组输出数据有什么原因吗?我相信一个物体在这里更适合1。所以这是我建议的修改函数:

const postData = "Port Main Num=No&Porting Type=PRO&Range Holder=TO POPULATE&Maintain DQ=No&Line Type=Multi&Associated Numbers=01111111111&Associated Numbers Actions=Port&Associated Numbers=02222222222&Associated Numbers Actions=Cease&Associated Numbers=01111122222&Associated Numbers Actions=Port&Title=Mr&Initial=t&Surname=Test&Account Number=01611111111&Company Name=Test Company&Building Name=&Address Line 1=Address Line 1&Address Line 2=&Town or City=Town&Postcode=BB1 1BB&Porting Date=08/10/2024&Main Billing Number=01611111111";

function parseFormData(postData) {
  var data = {};  // <-- Changed this.
  var parameters = postData.split('&');
  for (var i = 0; i < parameters.length; i++) {
    var keyValue = parameters[i].split('=');
    data[keyValue[0]] = data[keyValue[0]] ?
        data[keyValue[0]].concat(', ', decodeURIComponent(keyValue[1])) :
      decodeURIComponent(keyValue[1]);
  }
  return data;
}

console.log(parseFormData(postData));

参考文献


1数组 is,在 JavaScript 中,是一个对象;这正是您在函数中使用

data
数组的方式:向数组添加“隐藏”属性。


1
投票

您遇到了一件不寻常的事情,因为您使用一个空数组作为

data
的初始值,但您将其视为一个对象。在 JavaScript 中,数组只是一个具有整数键的对象,但从语义上讲它有点令人困惑。

但根本问题是对象键是唯一的,因此每次将对象的属性设置为特定值时,都会覆盖任何现有值:

data[keyValue[0]] = decodeURIComponent(keyValue[1]);

我建议:

  • 从空对象开始,
    {}
    而不是空数组
    []
  • 假设每个参数都是多值的
  • 将对象上每个属性的值设为数组
    []
    ,这在语义上意味着“事物列表”,然后为同一参数的每个值更新数组

您可以使用函数 reduce 很好地实现这一点,它是数组原型的一部分。如果您是新手,Reduce 可能需要您花点时间思考,但它是一个非常强大的工具,值得付出努力。

我的归约函数如下所示:

const POST_DATA = 'Port Main Num=No&Porting Type=PRO&Range Holder=TO POPULATE&Maintain DQ=No&Line Type=Multi&Associated Numbers=01111111111&Associated Numbers Actions=Port&Associated Numbers=02222222222&Associated Numbers Actions=Cease&Associated Numbers=01111122222&Associated Numbers Actions=Port&Title=Mr&Initial=t&Surname=Test&Account Number=01611111111&Company Name=Test Company&Building Name=&Address Line 1=Address Line 1&Address Line 2=&Town or City=Town&Postcode=BB1 1BB&Porting Date=08/10/2024&Main Billing Number=01611111111'

function parseFormData(postData = POST_DATA) {
  const data = postData.split('&').reduce((acc, param) => {
    const [key, value] = param.split('=');
    return {
      ...acc,
      [key]: [...(acc[key] || []), decodeURIComponent(value)]
    }
  }, {});
  console.log(data);
  return data;
}

parseFormData();

如果您不想使用reduce和spread运算符,以及在数组中条件包含的棘手小技巧,您可以这样做:

    const POST_DATA = 'Port Main Num=No&Porting Type=PRO&Range Holder=TO POPULATE&Maintain DQ=No&Line Type=Multi&Associated Numbers=01111111111&Associated Numbers Actions=Port&Associated Numbers=02222222222&Associated Numbers Actions=Cease&Associated Numbers=01111122222&Associated Numbers Actions=Port&Title=Mr&Initial=t&Surname=Test&Account Number=01611111111&Company Name=Test Company&Building Name=&Address Line 1=Address Line 1&Address Line 2=&Town or City=Town&Postcode=BB1 1BB&Porting Date=08/10/2024&Main Billing Number=01611111111'

    function parseFormData(postData = POST_DATA) {
      const data = {};
      for(parameter of postData.split('&')) {
        const [key, value] = parameter.split('=');
        data[key] = data[key] ?? []; // initialize to empty array, if it doesn't already exist;
        data[key].push(decodeURIComponent(value)); // push the new value into the array
      }
      return data;
    }

    console.log(parseFormData())

现在,所有多值查询参数都保留为可以在 JavaScript 中处理的列表,而无需不断拆分和重新连接它们。

您可以通过多种方式处理该问题,将这些值放入电子表格中。你可以:

  • 使用
    join(", ")
    或 `join(" ") 在将字符串写入工作表之前连接字符串
  • 如果您想将它们保留为电子表格中可独立引用的项目,您可以将它们写入单独的工作表中,并引用回行,就像数据库中的外键关系一样

这取决于您想要实现的目标。

© www.soinside.com 2019 - 2024. All rights reserved.