我有一个 HTML 网站,提交后,它会使用我现有的应用程序脚本填充我的 Google 表格。这一切都工作正常,但我遇到的问题是在我的网站中,我有一个
table
,它允许多行,每行都有一个 input
。
这是提交后发布到我的 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 表格时,它只填充最后输入的数字(这是我所期望的)
正如你从我的数据中看到的,我传递了所有 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);
}
问题出在你的
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
数组的方式:向数组添加“隐藏”属性。
您遇到了一件不寻常的事情,因为您使用一个空数组作为
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("
") 在将字符串写入工作表之前连接字符串这取决于您想要实现的目标。