[英]Creating spreadsheet from XLS through Google spreadsheet API with PHP and cURL
[英]Google API How to connect to receive values from spreadsheet
我开始着手这个项目,认为这很简单。 几个小时后,我意识到Google API有点迷宫,有多个API和库。 我真的需要明确指示如何去做这件事。
我创建了几个Google Doc电子表格,我已授予其他用户编辑权限。
我只需要使用PHP以编程方式从这些电子表格中检索信息。 但是,我无法弄清楚如何连接甚至开始检索。
这是我到目前为止所做的:
1 - 安装了Google PHP API库。
2 - 在同一帐户中创建了Google API项目。 我不知道我需要哪种API以及我需要哪些oAuth密钥。
3 - 从https://github.com/asimlqt/php-google-spreadsheet-client安装Google API电子表格客户端。
好吧,现在呢? 如何发送API命令以检索我想要的电子表格。 我不确定如何验证以及如何检索。 到目前为止,我使用API驱动程序的API服务器密钥尝试了以下....这只是一个猜测。 我在Google API电子表格客户端中复制并粘贴了以下示例:
<?php
require_once 'php-google-spreadsheet-client-master\src\Google\Spreadsheet\Autoloader.php';
$accessToken = 'xxxxxxxxxxxxxxxxxxxxxxx';
$request = new Google\Spreadsheet\Request($accessToken);
$serviceRequest = new Google\Spreadsheet\DefaultServiceRequest($request);
Google\Spreadsheet\ServiceRequestFactory::setInstance($serviceRequest);
$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
$spreadsheetFeed = $spreadsheetService->getSpreadsheets();
?>
我收到以下错误:
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in C:\php\php-google-spreadsheet-client-master\src\Google\Spreadsheet\SpreadsheetFeed.php:43 Stack trace: #0 C:\php\php-google-spreadsheet-client-master\src\Google\Spreadsheet\SpreadsheetFeed.php(43): SimpleXMLElement->__construct('') #1 C:\php\php-google-spreadsheet-client-master\src\Google\Spreadsheet\SpreadsheetService.php(39): Google\Spreadsheet\SpreadsheetFeed->__construct(false) #2 C:\php\google_docd.php(11): Google\Spreadsheet\SpreadsheetService->getSpreadsheets() #3 {main} thrown in C:\php\php-google-spreadsheet-client-master\src\Google\Spreadsheet\SpreadsheetFeed.php on line 43
拜托,拜托。 明确说明。 我是一个完整的Google API新手。 谢谢。 关于如何在SOAPUI中或通过bash进行测试的示例也会有所帮助,因为我可以使用它来弄清楚如何发出Curl请求。 非常感谢!
我终于让它工作了,尽管文件中的所有尝试都让它看起来不可能,这是我的设置:
您需要在API控制台上创建凭据: https : //console.developers.google.com/您需要首先创建一个项目并为您的应用创建一组身份验证信息:在左侧菜单中,单击API&Auth,然后是凭据。 单击“创建新客户端ID”(红色按钮),然后选择“服务帐户”。 您将下载文件,确保安全。 你将用你的脚本上传它。
此外,请注意:除非:我的文档是“旧电子表格”,否则它从未奏效。 我还需要与Google控制台上生成的用户ID(可能是电子邮件的用户ID)共享电子表格文档。 该文档包含一个使用适当的列名称(名称,年龄)冻结的顶行。
这是我与上面结合使用的php脚本:
<?php
require_once 'php-google-spreadsheet/src/Google/Spreadsheet/Autoloader.php';
require_once 'google-api-php-client/src/Google_Client.php';
const G_CLIENT_ID = 'fill_with_info_from_console.apps.googleusercontent.com';
const G_CLIENT_EMAIL = 'fill_with_info_from_console@developer.gserviceaccount.com';
const G_CLIENT_KEY_PATH = 'key/keep_the_complex_filename_here_privatekey.p12';
const G_CLIENT_KEY_PW = 'notasecret';
$obj_client_auth = new Google_Client ();
$obj_client_auth -> setApplicationName ('test_or_whatever_you_like');
$obj_client_auth -> setClientId (G_CLIENT_ID);
$obj_client_auth -> setAssertionCredentials (new Google_AssertionCredentials (
G_CLIENT_EMAIL,
array('https://spreadsheets.google.com/feeds','https://docs.google.com/feeds'),
file_get_contents (G_CLIENT_KEY_PATH),
G_CLIENT_KEY_PW
));
$obj_client_auth -> getAuth () -> refreshTokenWithAssertion ();
$obj_token = json_decode ($obj_client_auth -> getAccessToken ());
$accessToken = $obj_token->access_token;
$request = new Google\Spreadsheet\Request($accessToken);
$serviceRequest = new Google\Spreadsheet\DefaultServiceRequest($request);
Google\Spreadsheet\ServiceRequestFactory::setInstance($serviceRequest);
$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
$spreadsheetFeed = $spreadsheetService->getSpreadsheets();
$spreadsheet = $spreadsheetFeed->getByTitle('title_of_the_spreadsheet_doc');
$worksheetFeed = $spreadsheet->getWorksheets();
$worksheet = $worksheetFeed->getByTitle('title_of_the_tab');
$listFeed = $worksheet->getListFeed();
// this bit below will create a new row, only if you have a frozen first row adequatly labelled
$row = array('name'=>'John', 'age'=>25);
$listFeed->insert($row);
?>
我还应该注意:
所有这些仍然在进行中,但希望有助于某人为任何人写出惊人的指示,以便更好地理解细节。
这是来自谷歌文档的点点滴滴的汇编,有关stackoverflow的一些答案和来自2个api库的信息
让这个工作变得非常痛苦,它真的不应该; 我假设这是因为谷歌正在同时转换验证,控制台界面和api版本。
编辑:似乎谷歌文档中的列名称受到限制:不允许空格(?),不允许下划线(?),CamelCase似乎很麻烦。 我只是设法让破折号工作,就像“放置其他”一样,否则api抛出一些“未捕获的异常”
编辑:我使用完全相同的设置进行新项目仍然可行,最近谷歌引入了新的电子表格模型。 什么让我忘记了:不允许空白单元格,标题必须在没有空格的情况下冻结,并且从PHP查询时它们是小写的。
希望这可以帮助!
这个答案是jrgd的答案的附加组件,我在这里发布,作为答案,因为它包含代码。
连接问题本身让我感到困惑。 以下是我必须要解决的问题: 尝试获取Google accessToken 。 此外,电子表格必须与您在代码中找到的Google生成的电子邮件共享。
另外,jrgd,回答你关于该Request
对象的问题:它与Google Spreadsheet API不存在; / *当我使用Composer下载库时我找不到它* /相反,我最终做了GingerDog所做的事情:
$serviceRequest = new Google\\Spreadsheet\\DefaultServiceRequest($accessToken); Google\\Spreadsheet\\ServiceRequestFactory::setInstance($serviceRequest);
由于返回的HTTP错误代码高于300,因此在使用getSpreadsheets()
时代码抛出异常的可能性也很大。 SpreadsheetService
类有这个方法(这里是它的代码: /** * Fetches a list of spreadhsheet spreadsheets from google drive. * * @return \\Google\\Spreadsheet\\SpreadsheetFeed */ public function getSpreadsheets() { return new SpreadsheetFeed( ServiceRequestFactory::getInstance()->get('feeds/spreadsheets/private/full') ); }
请注意,还有另一个类“在这里做脏工作”: DefaultServiceRequest
类。这是正在的get()
用过的:
/**
* Perform a get request
*
* @param string $url
*
* @return string
*/
public function get($url)
{
$ch = $this->initRequest($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
return $this->execute($ch);
}
/**
* Executes the api request.
*
* @return string the xml response
*
* @throws \Google\Spreadsheet\Exception If the was a problem with the request.
* Will throw an exception if the response
* code is 300 or greater
*
* @throws \Google\Spreadsheet\UnauthorizedException
*/
protected function execute($ch)
{
$ret = curl_exec($ch);
$info = curl_getinfo($ch);
$httpCode = (int)$info['http_code'];
if($httpCode > 299) {
if($httpCode === 401) {
throw new UnauthorizedException('Access token is invalid', 401);
} else {
throw new Exception('Error in Google Request', $info['http_code']);
}
}
return $ret;
}
请注意,该函数从其最内层的帮助程序中有机会返回一个http_code
,该代码将导致代码抛出异常。 对商业不利。
解决方案
我纠正的方法是更改以下代码行: $spreadsheetFeed = $spreadsheetService->getSpreadsheets();
到这个while循环:
/* my way of "making" it work; // I just getSpreadsheets() until there stops being an exception thrown */
$googleException = new Exception();
while ($googleException != null)
{
try
{
$spreadsheetFeed = $spreadsheetService->getSpreadsheets(); # This line randomly throws exception, for some reason.
$googleException = null;
}
catch (Exception $e)
{
$googleException = $e;
}
}
//var_dump($spreadsheetFeed->getArrayCopy()); // test line
我在最近的项目中为Google表格身份验证和表格单元格编辑编写了一个包装类。 测试工作截至2015年9月2日,所以它是最新的!
先决条件:
要使用包装类:
// Initialise Google Sheets instance
$sheets = new GoogleSheets();
$sheets->clientID = 'YOUR CLIENT ID FROM GOOGLE DEV CONSOLE';
$sheets->clientEmail = 'YOUR CLIENT EMAIL FROM GOOGLE DEV CONSOLE';
$sheets->clientKeyPath = 'PATH TO THE P12 FILE YOU DOWNLOADED FROM GOOGLE DEV CONSOLE';
$sheets->clientKeyPw = 'IT IS USUALLY notasecret';
$sheets->appName = 'WHATEVER NAME YOU WANT';
$sheets->spreadsheetTitle = 'TITLE FOR THE SPREADSHEET YOU WANT TO EDIT';
$sheets->worksheetTitle = 'WORKSHEET TITLE IN THAT SPREADSHEET';
// Authenticate with Google
$sheets->authenticate();
// Now update the specific row cell
$sheets->updateListEntry(ROW_HEADER, $submissionID, CELL_HEADER, CELL_VALUE);
echo "updated!";
这里是包装类 - 随意修改它 - 大多数代码都是标准的样板代码。 经过测试工作!
// Autoload classes thanks to Composer
require_once('vendor/autoload.php');
class GoogleSheets {
// Instance variables
public $clientID, $clientEmail, $clientKeyPath, $clientKeyPw, $appName, $spreadsheetTitle, $worksheetTitle;
private $spreadsheetFeed;
// connect to Google using OAuth2, boilerplate code...
public function authenticate() {
$obj_client_auth = new Google_Client ();
$obj_client_auth -> setApplicationName ($this->appName);
$obj_client_auth -> setClientId ($this->clientID);
$obj_client_auth -> setAssertionCredentials (new Google_Auth_AssertionCredentials (
$this->clientEmail,
array('https://spreadsheets.google.com/feeds','https://docs.google.com/feeds'),
file_get_contents ($this->clientKeyPath),
$this->clientKeyPw
));
$obj_client_auth -> getAuth () -> refreshTokenWithAssertion ();
$obj_token = json_decode ($obj_client_auth -> getAccessToken ());
$accessToken = $obj_token->access_token;
$serviceRequest = new Google\Spreadsheet\DefaultServiceRequest($accessToken);
Google\Spreadsheet\ServiceRequestFactory::setInstance($serviceRequest);
$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
$this->spreadsheetFeed = $spreadsheetService->getSpreadsheets();
}
// Find matching row with header $field and cell value $value, and update cell with header $cellHeader to $cellValue
public function updateListEntry($field, $value, $cellHeader, $cellValue) {
// Get the required spreadsheet, then worksheet by title
$spreadsheet = $this->spreadsheetFeed->getByTitle($this->spreadsheetTitle);
$worksheetFeed = $spreadsheet->getWorksheets();
$worksheet = $worksheetFeed->getByTitle($this->worksheetTitle);
// sq stands for structured query
$listFeed = $worksheet->getListFeed(array("sq" => $field . " = " . $value));
$entries = $listFeed->getEntries();
$listEntry = $entries[0];
$values = $listEntry->getValues();
$values[$cellHeader] = $cellValue;
$listEntry->update($values);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.