Search code examples
phpgoogle-apigoogle-drive-apigoogle-api-php-clientgoogle-docs-api

How we can download a google docs into our local (computer)/hard drive using google docs api with PHP?


I want to download a google docs in PDF form in my local computer/hard drive after creating it using google docs api with PHP. For creating google docs I am using using below code from where I can get my document Id which i want to download.

$service = new Google_Service_Docs($client);

$title = 'Demo document';
$document = new Google_Service_Docs_Document([
    "title" => "Test1",
]);

$document = $service->documents->create($document);
$documentId = $document->getdocumentId();

and for download this file in my local, I gone through the documentation from this link https://developers.google.com/drive/api/v2/reference/files/get?apix_params=%7B%22fileId%22%3A%221v3DlRiUGic0oUFg3vJmKkZ2PyyG-PJTn0J2nftVtBfo%22%7D#examples , I was using this code -

$file = $service->files->get($documentId);
$downloadUrl = $file->getDownloadUrl();
  if ($downloadUrl) {
    $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
    $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
    if ($httpRequest->getResponseHttpCode() == 200) {
      return $httpRequest->getResponseBody();
    } else {
      // An error occurred.
      return null;
    }
  } else {
    // The file doesn't have any content stored on Drive.
    return null;
  }

but I am getting this error -

PHP Notice:  Undefined property: Google\Service\Docs::$files in 
PHP Fatal error:  Uncaught Error: Call to a member function export() on null 

Can anybody help me through this what mistake I am making and what else I have to do to achieve this.

I also tried like this but it also throwing me the same error-

$file = $service->files->export($documentId, 'application/pdf', array(
    'alt' => 'media' ));
$size = $file->getBody()->getSize();
if($size > 0) {
    $content = $file->getBody()->read($size);
}

edited code -

<?php
require __DIR__ . '/vendor/autoload.php';

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName('Google Docs API PHP Quickstart');
    $client->setScopes([
                        "https://www.googleapis.com/auth/documents",
                        "https://www.googleapis.com/auth/drive.file",
                        "https://www.googleapis.com/auth/drive",
                        Google_Service_Drive::DRIVE_READONLY,
                        ]);
    // $client->setScopes(Google_Service_Drive::DRIVE);
    $client->setAuthConfig('credentials.json');
    $client->setAccessType('offline');
    $client->setApprovalPrompt('force');

    // Load previously authorized credentials from a file.
    $credentialsPath = expandHomeDirectory('token.json');
    
    if (file_exists($credentialsPath)) {
        $accessToken = json_decode(file_get_contents($credentialsPath), true);
    } else {
        $authUrl = $client->createAuthUrl();
        printf("Open the following link in your browser:\n%s\n", $authUrl);
        print 'Enter verification code: ';        
        $authCode = trim(fgets(STDIN));
        $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
        if (!file_exists(dirname($credentialsPath))) {
            mkdir(dirname($credentialsPath), 0700, true);
        }
        file_put_contents($credentialsPath, json_encode($accessToken));
    }

    $client->setAccessToken($accessToken);
    // Refresh the token if it's expired.
    if ($client->isAccessTokenExpired()) {

        $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
       
        file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
    }
    
    return $client;
}

/**
 * Expands the home directory alias '~' to the full path.
 * @param string $path the path to expand.
 * @return string the expanded path.
 */
function expandHomeDirectory($path)
{
    $homeDirectory = getenv('HOME');
    if (empty($homeDirectory)) {
        $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
    }
    return str_replace('~', realpath($homeDirectory), $path);
}

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Docs($client);
$driveService = new Google_Service_Drive($client);

$title = 'Demo document';
$document = new Google_Service_Docs_Document([
    "title" => "Test1",
]);
$document = $service->documents->create($document);
$documentId = $document->getdocumentId();
$requests = [];
$index = 1;
$requests = [
    new Google_Service_Docs_Request([
        'insertTable' => [
            'location' => ['index' => $index],
            'columns' => 2,
            'rows' => 2
        ]
    ]),  
];
$batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest([
  'requests' => $requests
]);
$result = $service->documents->batchUpdate($documentId, $batchUpdateRequest);

$documentId = $document->getdocumentId();
$downloadUrl = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=pdf&id=" . $documentId;
$httpClient = $client->authorize();
$request = new GuzzleHttp\Psr7\Request('GET', $downloadUrl);
$response = $httpClient->send($request);
$file = $response->getBody();

Solution

  • In your situation, how about the following modification?

    1. Add a scope for exporting Google Document as a PDF data.

    If you are using the following script,

    $client->setScopes(Google_Service_Docs::DOCUMENTS);
    

    please modify as follows.

    $client->setScopes(array(Google_Service_Docs::DOCUMENTS,Google_Service_Drive::DRIVE_READONLY));
    

    When you add the scope, please remove the file including the access token and refresh token, and please authorize the scopes again.I thought that this might be the reason of your issue.

    2. Create an URL.

    In this case, I think that the exported URL can be created as a string value as follows.

    $downloadUrl = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=pdf&id=" . $documentId;
    

    3. Export Google Document as a PDF file.

    From your following script,

    $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
    $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
    

    I thought that you might use the older version of google-api-php-client. When you are required to use the older version, I think that by the above flow, you can export Google Document as a PDF file.

    But, if you update google-api-php-client, in the current version, the following script is used. Ref

    $documentId = "###"; // Please set Document ID. Or when your script is used, please use $documentId = $document->getdocumentId();
    $downloadUrl = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=pdf&id=" . $documentId;
    $httpClient = $client->authorize();
    $request = new GuzzleHttp\Psr7\Request('GET', $downloadUrl);
    $response = $httpClient->send($request);
    $file = $response->getBody(); // This is data of the exported PDF data.
    

    References: