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:
- Multi-method Authentication: Supports OAuth 2.0 (user-specific access), Service Account (server-to-server), and API key (public data access)
- Fluent API: Chainable methods for data and sheet operations with intuitive syntax
- Laravel Collection Integration: Seamlessly converts Google Sheets data into Laravel Collections for easy manipulation
- Extensibility: Macro system allows you to add custom methods to the main facade
- Drive Integration: Built-in Google Drive API support for spreadsheet management
Common Use Cases:
- User Dashboards: Display and interact with Google Sheets data in your application
- Import/Export: Bulk data operations between your Laravel app and Google Sheets
- Automated Reports: Generate and update reports programmatically
- Multi-user Applications: Each user can manage their own Google Sheets with proper authentication
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.
- PHP >= 8.2
- Laravel >= 11.0
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:
- Google Sheets API
- Google Drive API
-
Choose your authentication method and configure accordingly (see Authentication section below)
- Working Demo: Laravel Google Sheets Demo
- Example Project: google-sheets-project
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:
- Get an API Key from Google Cloud Console
- Ensure your spreadsheet is publicly accessible (shared with "Anyone with the link")
- Use the key in your application:
use Revolution\Google\Sheets\Facades\Sheets;
// API key is automatically used when configured
$values = Sheets::spreadsheet('public-spreadsheet-id')->sheet('Sheet1')->all();
- Read-only access
- Only works with publicly shared spreadsheets
- No write operations (update, append, delete)
- No access to private spreadsheets
Here's how to get started quickly with each authentication method:
- Setup: Follow the Service Account Setup Guide
- Configure: Add to your
.env
file:GOOGLE_SERVICE_ENABLED=true GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=storage/app/google-service-account.json
- Share: Share your Google Sheet with the service account email
- Use: Start reading/writing data:
use Revolution\Google\Sheets\Facades\Sheets; $values = Sheets::spreadsheet('your-spreadsheet-id') ->sheet('Sheet1') ->all();
- Setup: Follow the OAuth Setup Guide
- Configure: Add OAuth credentials to your
.env
file - Authenticate: Handle user authentication flow
- Use: Access user's spreadsheets:
use Revolution\Google\Sheets\Facades\Sheets; $token = ['access_token' => $user->access_token, ...]; $values = Sheets::setAccessToken($token) ->spreadsheet('user-spreadsheet-id') ->sheet('Sheet1') ->all();
- Setup: Get API key from Google Cloud Console
- Configure: Add to your
.env
file:GOOGLE_DEVELOPER_KEY=your-api-key
- Use: Read public spreadsheets:
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').
- 'A1' refers to the cell at column A and row 1.
- 'A1:B2' refers to the range from cell A1 to B2 (rectangle).
- 'A:B' refers to all rows in columns A and B.
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
- Service Account: Best for most Laravel applications, automated systems, and background jobs
- OAuth 2.0: Use when users need to access their own Google Sheets
- API Key: Only for reading public spreadsheets (very limited use cases)
- Open your Google Sheet
- Click the "Share" button
- Find the
client_email
in your service account JSON file - Share the spreadsheet with this email address
- Grant "Editor" permissions for read/write access
Yes! You can access any spreadsheet that:
- Is shared with your service account (Service Account method)
- The authenticated user has access to (OAuth method)
- Is publicly accessible (API Key method)
Common solutions:
- Service Account: Ensure the spreadsheet is shared with the service account email
- OAuth: Check if the access token is expired and refresh it
- API Key: Verify the spreadsheet is publicly accessible
- Store service account credentials securely (outside web root)
- Use environment variables for all configuration
- Never commit credential files to version control
- Consider using different service accounts for different environments
MIT License