revolution/laravel-google-sheets
This package provides a Laravel-idiomatic and streamlined interface for interacting with Google Sheets API v4. It abstracts away the underlying Google PHP client complexity, letting developers read, write, update, and manage spreadsheets with expressive, fluent methods that feel natural in Laravel applications.
Key Features:
Common Use Cases:
The main purpose of this package is reading from Google Sheets. Instead of specifying detailed conditions before reading, it is assumed that you first retrieve all data as a Laravel Collection and then process the data on the Laravel side.
composer require revolution/laravel-google-sheets
Run php artisan vendor:publish --tag="google-config" to publish the google config file
Enable Google APIs in Google Cloud Console:
Choose your authentication method and configure accordingly (see Authentication section below)
Related Google API Packages:
You must choose an authentication method based on your use case. This package supports three authentication methods:
Scopes setting is required in config/google.php for both OAuth and Service Account authentication. Example:
'scopes' => [ \Google\Service\Sheets::SPREADSHEETS, \Google\Service\Drive::DRIVE, ],
| Method | Use Case | User Interaction | Access Scope | Complexity |
|---|---|---|---|---|
| Service Account | Server-to-server, automated systems | None required | Specific spreadsheets you own/share | Medium |
| OAuth 2.0 | User-facing applications | User consent required | User's own spreadsheets | High |
| API Key | Public data only | None required | Public spreadsheets only | Low |
Best for: Background jobs, automated systems, server-to-server access
Access spreadsheets that your application owns or has been granted access to. No user interaction required.
GOOGLE_SERVICE_ENABLED=true
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=storage/app/google-service-account.json
📖 Complete Service Account Setup Guide →
Best for: Applications where users access their own Google Sheets
Users grant permission to access their personal Google Sheets. Requires user consent flow.
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT=https://your-app.com/auth/callback
📖 Complete OAuth Setup Guide →
Best for: Accessing publicly shared, read-only spreadsheets
Limited to reading data from spreadsheets that are publicly accessible. No authentication flow required.
GOOGLE_DEVELOPER_KEY=your-api-key
To use API Key authentication:
use Revolution\Google\Sheets\Facades\Sheets;
// API key is automatically used when configured
$values = Sheets::spreadsheet('public-spreadsheet-id')->sheet('Sheet1')->all();
⚠️ API Key Limitations:
Here's how to get started quickly with each authentication method:
.env file:
GOOGLE_SERVICE_ENABLED=true
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=storage/app/google-service-account.json
use Revolution\Google\Sheets\Facades\Sheets;
$values = Sheets::spreadsheet('your-spreadsheet-id')
->sheet('Sheet1')
->all();
.env fileuse Revolution\Google\Sheets\Facades\Sheets;
$token = ['access_token' => $user->access_token, ...];
$values = Sheets::setAccessToken($token)
->spreadsheet('user-spreadsheet-id')
->sheet('Sheet1')
->all();
.env file:
GOOGLE_DEVELOPER_KEY=your-api-key
use Revolution\Google\Sheets\Facades\Sheets;
// Works only with publicly shared spreadsheets
$values = Sheets::spreadsheet('public-spreadsheet-id')
->sheet('Sheet1')
->all();
Consider this example spreadsheet structure:
| id | name | |
|---|---|---|
| 1 | name1 | mail1 |
| 2 | name2 | mail2 |
Spreadsheet URL: https://docs.google.com/spreadsheets/d/{spreadsheetID}/...
When using Service Account authentication, no token setup is required:
use Revolution\Google\Sheets\Facades\Sheets;
// Service account authentication is automatic when configured
$values = Sheets::spreadsheet('spreadsheetId')->sheet('Sheet 1')->all();
// [
// ['id', 'name', 'mail'],
// ['1', 'name1', 'mail1'],
// ['2', 'name2', 'mail2']
// ]
When using OAuth authentication, you need to set the user's access token:
use Revolution\Google\Sheets\Facades\Sheets;
$user = $request->user();
$token = [
'access_token' => $user->access_token,
'refresh_token' => $user->refresh_token,
'expires_in' => $user->expires_in,
'created' => $user->updated_at->getTimestamp(),
];
// all() returns array
$values = Sheets::setAccessToken($token)->spreadsheet('spreadsheetId')->sheet('Sheet 1')->all();
// [
// ['id', 'name', 'mail'],
// ['1', 'name1', 'mail1'],
// ['2', 'name1', 'mail2']
// ]
Collection conversion is simple and subsequent processing is flexible, so this method is recommended.
use Revolution\Google\Sheets\Facades\Sheets;
// get() returns Laravel Collection
$rows = Sheets::sheet('Sheet 1')->get();
$header = $rows->pull(0);
$values = Sheets::collection(header: $header, rows: $rows);
$values->toArray()
// [
// ['id' => '1', 'name' => 'name1', 'mail' => 'mail1'],
// ['id' => '2', 'name' => 'name2', 'mail' => 'mail2']
// ]
Blade
@foreach($values as $value)
{{ data_get($value, 'name') }}
@endforeach
use Revolution\Google\Sheets\Facades\Sheets;
$values = Sheets::sheet('Sheet 1')->range('A1:B2')->all();
// [
// ['id', 'name'],
// ['1', 'name1'],
// ]
A1 Notation is the standard way to specify a cell or range in Google Sheets (e.g., 'A1', 'A1:B2').
If you are not familiar with A1 Notation or your range is dynamic/complicated, it is often easier to fetch all data and use Laravel Collections to process/filter it after retrieval.
use Revolution\Google\Sheets\Facades\Sheets;
Sheets::sheet('Sheet 1')->range('A4')->update([['3', 'name3', 'mail3']]);
$values = Sheets::range('')->all();
// [
// ['id', 'name', 'mail'],
// ['1', 'name1', 'mail1'],
// ['2', 'name1', 'mail2'],
// ['3', 'name3', 'mail3']
// ]
use Revolution\Google\Sheets\Facades\Sheets;
// When we don't provide a specific range, the sheet becomes the default range
Sheets::sheet('Sheet 1')->append([['3', 'name3', 'mail3']]);
$values = Sheets::all();
// [
// ['id', 'name', 'mail'],
// ['1', 'name1', 'mail1'],
// ['2', 'name1', 'mail2'],
// ['3', 'name3', 'mail3']
// ]
use Revolution\Google\Sheets\Facades\Sheets;
// When providing an associative array, values get matched up to the headers in the provided sheet
Sheets::sheet('Sheet 1')->append([['name' => 'name4', 'mail' => 'mail4', 'id' => 4]]);
$values = Sheets::all();
// [
// ['id', 'name', 'mail'],
// ['1', 'name1', 'mail1'],
// ['2', 'name1', 'mail2'],
// ['3', 'name3', 'mail3'],
// ['4', 'name4', 'mail4'],
// ]
use Revolution\Google\Sheets\Facades\Sheets;
Sheets::spreadsheetByTitle($title)->addSheet('New Sheet Title');
use Revolution\Google\Sheets\Facades\Sheets;
Sheets::spreadsheetByTitle($title)->deleteSheet('Old Sheet Title');
use Revolution\Google\Sheets\Facades\Sheets;
$values = Sheets::sheet('Sheet 1')->majorDimension('DIMENSION_UNSPECIFIED')
->valueRenderOption('FORMATTED_VALUE')
->dateTimeRenderOption('SERIAL_NUMBER')
->all();
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get#query-parameters
use Revolution\Google\Sheets\Facades\Sheets;
$sheets->spreadsheets->...
$sheets->spreadsheets_sheets->...
$sheets->spreadsheets_values->...
Sheets::getService()->spreadsheets->...
see https://github.com/google/google-api-php-client-services/blob/master/src/Google/Service/Sheets.php
client_email in your service account JSON fileYes! You can access any spreadsheet that:
Common solutions:
MIT License
How can I help you explore Laravel packages today?