通过 API 添加行到 Google 电子表格
Add row to Google Spreadhseet via API
我正在构建一个 Chrome 扩展,它将新行写入 Google Spreadsheet。我设法阅读了 sheet 内容,但无法再写一行。目前我的错误是“400(错误请求)”。知道我在这里做错了什么吗?
我已查看 Google Sheets API documentation 和此处发布的其他问题,但未能找到任何解决方案。
这是我用来获取 sheet 内容的代码(有效):
function loadSpreadsheet(token) {
var y = new XMLHttpRequest();
y.open('GET', 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/values?access_token=' + token);
y.onload = function() {
console.log(y.response);
};
y.send();
}
这是我尝试 POST 新行的代码(给我“400 - 错误请求”):
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',//'--END_OF_PART\r\n',
'<gsx:name>',foo,'</gsx:name>',//'--END_OF_PART\r\n',
'</entry>'].join('');
return atom;
};
var params = {
'body': constructAtomXML("foo")
};
url = 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
注意:spreadsheet_id 是我实际 sheet ID 的占位符。
遵循协议并使其发挥作用。
假设电子表格 ID 是 '1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8'
首先使用电子表格 ID 检索工作表列表:
在那里您可以阅读工作表及其 ID 的列表。让我们使用示例中的第一个工作表。您会在 feed > entry[0] > link
数组中找到它的 ID。寻找 "rel" 等于 'http://schemas.google.com/spreadsheets/2006#listfeed'.
在我的示例中,此工作表的 URL 是(工作表 URL):https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full
现在,要阅读其内容,请使用:
GET [工作表 URL]?alt=json
除了列表行提要之外,您还会发现 "post" URL 应该用于使用列表行提要来更改电子表格。这是 "rel" 等于 feed > link
下的“http://schemas.google.com/g/2005#post”。
刚好和GET请求一样URL。在我的例子中:https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full。请确保不要附加 alt=json.
现在,要使用列表行提要插入新行,您需要发送 POST 以及文档中指定的负载。您需要发送一个以 "gsx:" 为前缀的列名称作为标记名称。但是,它可能与电子表格中的列名称不同。您需要删除所有空格,将其全部小写并且没有任何国家字符。因此,为了让您的示例正常工作,您需要将 <gsx:Name>
替换为 <gsx:name>
。
在更改之前,您可能有以下有效负载消息:
Blank rows cannot be written; use delete instead.
是因为API不理解"Name"是什么,所以在请求中丢掉了这部分条目。没有它就没有更多的项目并且该行是空白的。
或者,您可以从 GET 响应中读取列名。 feed > entry
数组中以 gsk$
开头的对象的键是列定义($ 符号后的所有内容都是列名)。
============================================= ====================
编辑
回答评论中的问题。
我从你的例子中改变了两点:
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',
'<gsx:name>',foo,'</gsx:name>',
'</entry>'].join('');
return atom;
};
/*
var params = {
'body': constructAtomXML("foo")
};
*/
var params = constructAtomXML("foo");
url = 'https://spreadsheets.google.com/feeds/list/'+spredsheetId+'/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
1) <gsx:Name>
到 <gsx:name>
。没有它你会收到一个错误。
2) params
对象应该是一个字符串!不是带有某些 'body' 键的对象。你只需要传递一个你想发送到服务器的值。
我正在构建一个 Chrome 扩展,它将新行写入 Google Spreadsheet。我设法阅读了 sheet 内容,但无法再写一行。目前我的错误是“400(错误请求)”。知道我在这里做错了什么吗?
我已查看 Google Sheets API documentation 和此处发布的其他问题,但未能找到任何解决方案。
这是我用来获取 sheet 内容的代码(有效):
function loadSpreadsheet(token) {
var y = new XMLHttpRequest();
y.open('GET', 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/values?access_token=' + token);
y.onload = function() {
console.log(y.response);
};
y.send();
}
这是我尝试 POST 新行的代码(给我“400 - 错误请求”):
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',//'--END_OF_PART\r\n',
'<gsx:name>',foo,'</gsx:name>',//'--END_OF_PART\r\n',
'</entry>'].join('');
return atom;
};
var params = {
'body': constructAtomXML("foo")
};
url = 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
注意:spreadsheet_id 是我实际 sheet ID 的占位符。
遵循协议并使其发挥作用。
假设电子表格 ID 是 '1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8'
首先使用电子表格 ID 检索工作表列表:
在那里您可以阅读工作表及其 ID 的列表。让我们使用示例中的第一个工作表。您会在 feed > entry[0] > link
数组中找到它的 ID。寻找 "rel" 等于 'http://schemas.google.com/spreadsheets/2006#listfeed'.
在我的示例中,此工作表的 URL 是(工作表 URL):https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full
现在,要阅读其内容,请使用:
GET [工作表 URL]?alt=json
除了列表行提要之外,您还会发现 "post" URL 应该用于使用列表行提要来更改电子表格。这是 "rel" 等于 feed > link
下的“http://schemas.google.com/g/2005#post”。
刚好和GET请求一样URL。在我的例子中:https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full。请确保不要附加 alt=json.
现在,要使用列表行提要插入新行,您需要发送 POST 以及文档中指定的负载。您需要发送一个以 "gsx:" 为前缀的列名称作为标记名称。但是,它可能与电子表格中的列名称不同。您需要删除所有空格,将其全部小写并且没有任何国家字符。因此,为了让您的示例正常工作,您需要将 <gsx:Name>
替换为 <gsx:name>
。
在更改之前,您可能有以下有效负载消息:
Blank rows cannot be written; use delete instead.
是因为API不理解"Name"是什么,所以在请求中丢掉了这部分条目。没有它就没有更多的项目并且该行是空白的。
或者,您可以从 GET 响应中读取列名。 feed > entry
数组中以 gsk$
开头的对象的键是列定义($ 符号后的所有内容都是列名)。
============================================= ====================
编辑
回答评论中的问题。
我从你的例子中改变了两点:
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',
'<gsx:name>',foo,'</gsx:name>',
'</entry>'].join('');
return atom;
};
/*
var params = {
'body': constructAtomXML("foo")
};
*/
var params = constructAtomXML("foo");
url = 'https://spreadsheets.google.com/feeds/list/'+spredsheetId+'/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
1) <gsx:Name>
到 <gsx:name>
。没有它你会收到一个错误。
2) params
对象应该是一个字符串!不是带有某些 'body' 键的对象。你只需要传递一个你想发送到服务器的值。