revolution/laravel-google-sheets
Installation:
composer require revolution/laravel-google-sheets
Publish the config file:
php artisan vendor:publish --provider="Revolution\GoogleSheets\GoogleSheetsServiceProvider"
Configuration:
Edit .env with your Google API credentials (OAuth, Service Account, or API Key) and configure in config/googlesheets.php:
GOOGLE_SHEETS_AUTH=service_account
GOOGLE_SHEETS_CREDENTIALS=path/to/service-account.json
First Use Case: Fetch a sheet as a Laravel Collection:
use Revolution\GoogleSheets\Facades\GoogleSheets;
$data = GoogleSheets::spreadsheet('your-spreadsheet-id')
->sheet('Sheet1')
->get()
->toCollection();
Read Data:
$data = GoogleSheets::spreadsheet('id')
->sheet('Sheet1')
->range('A1:B10')
->get()
->toCollection();
range() to specify cell ranges (e.g., 'A1:C100').toCollection() for Laravel Collection integration.Write Data:
GoogleSheets::spreadsheet('id')
->sheet('Sheet1')
->range('A1')
->update([['Name', 'Age'], ['John', 30]]);
update() for bulk writes or set() for single-cell updates.Append Data:
GoogleSheets::spreadsheet('id')
->sheet('Sheet1')
->range('A1')
->append([['New', 'Data']]);
Service Account (Server-to-Server):
Configure in .env and use default facade methods. Ideal for automated scripts.
OAuth (User-Specific): Redirect users to Google OAuth flow:
$authUrl = GoogleSheets::auth()->getAuthorizationUrl();
Exchange code for tokens:
$tokens = GoogleSheets::auth()->exchangeCodeForToken($code);
Store tokens in the database for future use.
API Key (Public Data): Use for read-only access to public sheets:
config(['googlesheets.auth' => 'api_key']);
config(['googlesheets.api_key' => 'YOUR_API_KEY']);
$spreadsheets = GoogleSheets::drive()->list();
$spreadsheet = GoogleSheets::drive()->create('New Spreadsheet');
batch() to group multiple operations:
GoogleSheets::spreadsheet('id')->batch(function ($batch) {
$batch->sheet('Sheet1')->range('A1')->update([['Data', 1]]);
$batch->sheet('Sheet2')->range('B1')->set('Updated');
});
Macros for Custom Methods: Extend the facade in a service provider:
GoogleSheets::macro('exportToCsv', function ($spreadsheetId, $sheetName, $filePath) {
$data = $this->spreadsheet($spreadsheetId)->sheet($sheetName)->get()->toArray();
file_put_contents($filePath, $this->arrayToCsv($data));
});
Usage:
GoogleSheets::exportToCsv('id', 'Sheet1', 'export.csv');
Events: Listen for sheet updates:
GoogleSheets::spreadsheet('id')->sheet('Sheet1')->onUpdate(function ($data) {
Log::info('Sheet updated:', $data);
});
Authentication Errors:
Invalid credentials or User does not have permission..env and config/googlesheets.php settings.Rate Limiting:
GoogleSheets::spreadsheet()->batch() to reduce API calls. Cache responses when possible:
$data = Cache::remember("sheet_{$spreadsheetId}", now()->addHours(1), function () {
return GoogleSheets::spreadsheet($spreadsheetId)->sheet('Sheet1')->get();
});
Data Type Mismatches:
$collection = GoogleSheets::spreadsheet('id')->sheet('Sheet1')->get()
->map(function ($row) {
return collect($row)->zip(['Name', 'Age'])->toArray();
});
Time Zones and Dates:
44561.542 = 2021-01-01 13:00:00).$date = Carbon\Carbon::createFromTimestamp($serialNumber);
Large Datasets:
range() to fetch specific chunks or paginate:
$batchSize = 1000;
for ($i = 1; $i <= 100; $i++) {
$data = GoogleSheets::spreadsheet('id')
->sheet('Sheet1')
->range("A1:A{$batchSize}")
->get();
// Process $data
}
Service Account Scopes:
https://www.googleapis.com/auth/spreadsheets and https://www.googleapis.com/auth/drive are included in the JSON key file.Caching:
GoogleSheets::clearCache();
Environment-Specific Config:
config() method to override settings dynamically:
config(['googlesheets.auth' => env('GOOGLE_SHEETS_AUTH', 'service_account')]);
Custom Responses:
Revolution\GoogleSheets\Sheets\Sheet class:
namespace App\Extensions;
use Revolution\GoogleSheets\Sheets\Sheet;
class CustomSheet extends Sheet {
public function toCustomFormat() {
return $this->get()->map(fn ($row) => (object) $row);
}
}
GoogleSheets::extend('custom', function () {
return new CustomSheet();
});
GoogleSheets::spreadsheet('id')->custom()->toCustomFormat();
Webhooks:
GoogleSheets::drive()->pushNotification(
'https://your-app.com/google-sheets-webhook',
['spreadsheets']
);
Route::post('/google-sheets-webhook', function (Request $request) {
$channelId = $request->input('channel.id');
GoogleSheets::drive()->acknowledge($channelId);
// Process update
});
Testing:
GoogleSheets facade:
GoogleSheets::shouldReceive('spreadsheet')
->once()
->with('test-id')
->andReturnSelf();
GoogleSheets::shouldReceive('sheet')
->once()
->with('TestSheet')
->andReturnSelf();
GoogleSheets::shouldReceive('get')
->once()
->andReturn(collect([['Test', 'Data']]));
How can I help you explore Laravel packages today?