通过 api 3.0 更改 Google 电子表格上的单元格内容
我需要更改谷歌电子表格上单元格的内容。
我已经通过 google docs api 成功获取了数据(设置了所有必需的授权和选项标签)。
但我无法更改单元格内容。我生成了以下网址和数据:
req url: https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1
req data: <?xml version='1.0' encoding='UTF-8'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'><id>https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1</id><link rel='edit' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1'/><gs:cell row='2' col='1' inputValue='*match found*
имя: вася
фамилия: тра та та
номер телефона дом: +7123456789
номер телефона моб: +7098765432
город: москва'/></entry>
repl data: Response contains no content type
有时我会收到“错误请求”回复。
我在编写代码时遵循此文档,然后创建:
1.我得到 cellsfeed url
NETLIBHTTPREQUEST nlhr = {0};
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.headersCount = 2;
nlhr.headers = (NETLIBHTTPHEADER*)malloc(sizeof(NETLIBHTTPHEADER) * (nlhr.headersCount));
nlhr.headers[0].szName = "Authorization";
if(AuthTag.empty())
{
string str;
str += "GoogleLogin auth=";
str += Auth;
AuthTag = str;
nlhr.headers[0].szValue = _strdup(str.c_str());
}
else
nlhr.headers[0].szValue = _strdup(AuthTag.c_str());
nlhr.headers[1].szName = "GData-Version";
nlhr.headers[1].szValue = "3.0";
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.flags = NLHRF_SSL;
{
string str = "https://spreadsheets.google.com/feeds/worksheets/";
str += toUTF8(Params.vtszDocuments[0]);
str += "/private/full";
nlhr.szUrl = _strdup(str.c_str());
}
nlhr.requestType = REQUEST_GET;
nlhr2 = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr);
if(!nlhr2)
{
boost::this_thread::sleep(boost::posix_time::minutes(Params.Interval));
continue;
}
using namespace rapidxml;
xml_document<> xml;
xml.parse<0>(nlhr2->pData);
Netlib_CloseHandle(nlhr2);
for(xml_node<> *node = xml.first_node()->first_node("entry"); node; node = node->next_sibling("entry"))
{
if(strcmp(node->first_node("title")->value(), toUTF8(Params.tszListName).c_str()))
continue;
bool found = false;
xml_node<> *id = node->first_node("id");
string spreadshit_id = id->value();
if(spreadshit_id.find(toUTF8(Params.vtszDocuments[0])) == string::npos)
continue;
for(xml_node<> *link = node->first_node("link"); link; link = link->next_sibling("link"))
{
if(strcmp(link->first_attribute("rel")->value(), "http://schemas.google.com/spreadsheets/2006#cellsfeed"))
continue;
cellsfeed = link->first_attribute("href")->value();
found = true;
if(found)
break;
}
if(found)
break;
}
2。我将细胞送入缓冲区以便根据需要进行解析
base_document_xml.clear();
if(base_document_xml_buffer)
free(base_document_xml_buffer);
NETLIBHTTPREQUEST nlhr = {0};
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.headersCount = 2;
nlhr.headers = (NETLIBHTTPHEADER*)malloc(sizeof(NETLIBHTTPHEADER) * (nlhr.headersCount));
nlhr.headers[0].szName = "Authorization";
if(AuthTag.empty())
{
string str;
str += "GoogleLogin auth=";
str += Auth;
AuthTag = str;
nlhr.headers[0].szValue = _strdup(str.c_str());
}
else
nlhr.headers[0].szValue = _strdup(AuthTag.c_str());
nlhr.headers[1].szName = "GData-Version";
nlhr.headers[1].szValue = "3.0";
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.flags = NLHRF_SSL;
nlhr.szUrl = _strdup(cellsfeed.c_str());
nlhr.requestType = REQUEST_GET;
nlhr2 = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr);
if(!nlhr2)
{
boost::this_thread::sleep(boost::posix_time::minutes(Params.Interval));
continue;
}
using namespace rapidxml;
base_document_xml_buffer = _strdup(nlhr2->pData);
base_document_xml.parse<0>(base_document_xml_buffer); //memory leak ?
Netlib_CloseHandle(nlhr2);
3。我获取 etag 并编辑所需单元格的 url
string edit_link, etag;
using namespace rapidxml;
for(xml_node<> *node = base_document_xml.first_node()->first_node("entry"); node; node = node->next_sibling("entry"))
{
xml_node<> *cell_id = node->first_node("gs:cell");
char buf[4];
_itoa(i->row +1 ,buf, 10);
if(strcmp(cell_id->first_attribute("row")->value(), buf))
continue;
_itoa(i->column +1 ,buf, 10);
if(strcmp(cell_id->first_attribute("col")->value(), buf))
continue;
for(xml_node<> *link = node->first_node("link"); link; link = link->next_sibling("link"))
{
if(strcmp(link->first_attribute("rel")->value() , "edit"))
continue;
edit_link = link->first_attribute("href")->value();
etag = node->first_attribute("gd:etag")->value();
}
}
我在此代码中使用 Miranda IM 核心网络库,我认为网络部分没问题,请求 url 或请求中的数据内容有问题
UPD:
我在第一个代码中错过了内容类型标头,现在我修复了这个问题,但还有另一个问题,谷歌返回“文件过早结束”...,代码已更新。
UPD2:
我已经解决了这个问题,它是由netowrk库传递的错误参数引起的,现在我有以下网格id的查询参数值无效。,并且不明白这意味着什么...
UPD3:
看起来我误解了API,我需要重写一些代码,我将在这里发布结果...
UPD4:
我尝试过通过不同的api函数获取编辑url,但是具有相同的结果...
UPD5:
我已经解决了这个问题,不是最佳的,我认为速度很慢,但至少可以工作,我实现了更多的 api 调用和附加 xml 解析步骤以获得正确的链接编辑每个单元格,如果有人需要的话更新代码,这里使用rapidxml解析库和miranda im core net库。
I need to change the contents of a cell on google spreadsheets.
I have successfully gotten the data via google docs api (all required authorization and options tag are set).
But I can't change the cell content. I have generated the following url and data:
req url: https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1
req data: <?xml version='1.0' encoding='UTF-8'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'><id>https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1</id><link rel='edit' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/cells/0AnT0uFQJWw_edENkYndfQWxCWlVmeG9oNW5kWjhYVUE/tCdbw_AlBZUfxoh5ndZ8XUA/private/full/R2C1'/><gs:cell row='2' col='1' inputValue='*match found*
имя: вася
фамилия: тра та та
номер телефона дом: +7123456789
номер телефона моб: +7098765432
город: москва'/></entry>
repl data: Response contains no content type
And sometimes I recieve "bad request" in reply.
i following this document when writing code, and create this:
1. i getting cellsfeed url
NETLIBHTTPREQUEST nlhr = {0};
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.headersCount = 2;
nlhr.headers = (NETLIBHTTPHEADER*)malloc(sizeof(NETLIBHTTPHEADER) * (nlhr.headersCount));
nlhr.headers[0].szName = "Authorization";
if(AuthTag.empty())
{
string str;
str += "GoogleLogin auth=";
str += Auth;
AuthTag = str;
nlhr.headers[0].szValue = _strdup(str.c_str());
}
else
nlhr.headers[0].szValue = _strdup(AuthTag.c_str());
nlhr.headers[1].szName = "GData-Version";
nlhr.headers[1].szValue = "3.0";
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.flags = NLHRF_SSL;
{
string str = "https://spreadsheets.google.com/feeds/worksheets/";
str += toUTF8(Params.vtszDocuments[0]);
str += "/private/full";
nlhr.szUrl = _strdup(str.c_str());
}
nlhr.requestType = REQUEST_GET;
nlhr2 = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr);
if(!nlhr2)
{
boost::this_thread::sleep(boost::posix_time::minutes(Params.Interval));
continue;
}
using namespace rapidxml;
xml_document<> xml;
xml.parse<0>(nlhr2->pData);
Netlib_CloseHandle(nlhr2);
for(xml_node<> *node = xml.first_node()->first_node("entry"); node; node = node->next_sibling("entry"))
{
if(strcmp(node->first_node("title")->value(), toUTF8(Params.tszListName).c_str()))
continue;
bool found = false;
xml_node<> *id = node->first_node("id");
string spreadshit_id = id->value();
if(spreadshit_id.find(toUTF8(Params.vtszDocuments[0])) == string::npos)
continue;
for(xml_node<> *link = node->first_node("link"); link; link = link->next_sibling("link"))
{
if(strcmp(link->first_attribute("rel")->value(), "http://schemas.google.com/spreadsheets/2006#cellsfeed"))
continue;
cellsfeed = link->first_attribute("href")->value();
found = true;
if(found)
break;
}
if(found)
break;
}
2. i getting cellsfeed to buffer for parsing on need
base_document_xml.clear();
if(base_document_xml_buffer)
free(base_document_xml_buffer);
NETLIBHTTPREQUEST nlhr = {0};
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.headersCount = 2;
nlhr.headers = (NETLIBHTTPHEADER*)malloc(sizeof(NETLIBHTTPHEADER) * (nlhr.headersCount));
nlhr.headers[0].szName = "Authorization";
if(AuthTag.empty())
{
string str;
str += "GoogleLogin auth=";
str += Auth;
AuthTag = str;
nlhr.headers[0].szValue = _strdup(str.c_str());
}
else
nlhr.headers[0].szValue = _strdup(AuthTag.c_str());
nlhr.headers[1].szName = "GData-Version";
nlhr.headers[1].szValue = "3.0";
nlhr.cbSize = sizeof(NETLIBHTTPREQUEST);
nlhr.flags = NLHRF_SSL;
nlhr.szUrl = _strdup(cellsfeed.c_str());
nlhr.requestType = REQUEST_GET;
nlhr2 = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr);
if(!nlhr2)
{
boost::this_thread::sleep(boost::posix_time::minutes(Params.Interval));
continue;
}
using namespace rapidxml;
base_document_xml_buffer = _strdup(nlhr2->pData);
base_document_xml.parse<0>(base_document_xml_buffer); //memory leak ?
Netlib_CloseHandle(nlhr2);
3. i getting etag and edit url for needed cell
string edit_link, etag;
using namespace rapidxml;
for(xml_node<> *node = base_document_xml.first_node()->first_node("entry"); node; node = node->next_sibling("entry"))
{
xml_node<> *cell_id = node->first_node("gs:cell");
char buf[4];
_itoa(i->row +1 ,buf, 10);
if(strcmp(cell_id->first_attribute("row")->value(), buf))
continue;
_itoa(i->column +1 ,buf, 10);
if(strcmp(cell_id->first_attribute("col")->value(), buf))
continue;
for(xml_node<> *link = node->first_node("link"); link; link = link->next_sibling("link"))
{
if(strcmp(link->first_attribute("rel")->value() , "edit"))
continue;
edit_link = link->first_attribute("href")->value();
etag = node->first_attribute("gd:etag")->value();
}
}
i using Miranda IM core network library in this code, and i think all right with network part, something wrong with request url or data content in request
UPD:
i have missed content type header in first code, now i fixed this, but have another problem, google returning "premature end of file"..., code updated.
UPD2:
i have solve this problem, it caused by wrong parameters passed by netowrk library, now i have following Invalid query parameter value for grid-id., and does not understand what it means...
UPD3:
looks like i have misunderstand api, i need to rewrite some code, i will post result here...
UPD4:
i have tried to obtain edit url via different api function, but have same result ...
UPD5:
i have solved this problem, not optimal and i thnk slow way, but at least working, i implement few more api calls and addition xml parsing steps to get correct link for edit each cell, code updated if someone need this, rapidxml parsing library and miranda im core net library used here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论