phpgoogle-docsgoogle-docs-api

Is it possible to insert a Horizontal Rule with Google Docs API?


I've been working on a project that needs to insert both text and other types of elements into a Google Docs Document, using PHP. I'm able to insert text using the following code:

    $requests = [];
    ```
    $requests[] = new \Google_Service_Docs_Request(
        ['insertText' => ['text' => 'Text to insert',
                          'location' => ['index' => $insertionIndex],
                          ],
         ]);
    ```
    $batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(['requests' => $requests]);
    $docsService->documents->batchUpdate($documentID, $batchUpdateRequest);

I can also insert a page break with a similar call:

    $requests = [];
    ```
    $requests[] = new \Google_Service_Docs_Request(
        ['insertPageBreak' => ['location' => ['index' => $insertionIndex],
                               ],
         ]);
    ```
    $batchUpdateRequest = new \Google_Service_Docs_BatchUpdateDocumentRequest(['requests' => $requests]);
    $docsService->documents->batchUpdate($documentID, $batchUpdateRequest);

Both of the above work fine (and as per Google's recommendations when I am carrying out multiple insertions I am working backwards). What I need to be able to do is add a horizontal rule to the document. I know Google Docs allows the manual insertion of them and Apps Script supports insertHorizontalRule but the Docs API doesn't seem to have an equivalent. I have searched here, Google, and the API documentation and can't find any reference to it. Could someone tell me if it is possible? If it is possible, what is the correct request type?

It's seems additionally strange that there isn't a documented way of inserting them, and yet you can query the contents of an existing document and any that are in the document are reported back to you as part of its structure.

For clarity of purpose, I am trying to append the contents of one Google Doc to the another. If anyone knows of a better way to do this than consuming the source document element by element and creating a request to add those elements to the destination document, that would bypass the need to handle inserting a horizontal rule.


Solution

  • I could understand like above. Unfortunately, in the current stage, it seems that there are no methods for adding the horizontal rule in Google Docs API yet, while "horizontalRule" can be retrieved by documents.get. Docs API is growing now. So this might be added in the future update.

    So in the current stage, it is required to use the workaround for this.

    Pattern 1:

    In this pattern, the horizontal rule is added to Google Document using Web Apps created by Google Apps Script as an API.

    Usage:

    1. Set Web Apps Script:

    Please copy and paste the following script to the script editor for Google Apps Script.

    function doGet(e) {
      DocumentApp.openById(e.parameter.id).getBody().insertHorizontalRule(Number(e.parameter.index) - 1);
      return ContentService.createTextOutput("Done");
    }
    

    2. Deploy Web Apps:

    1. On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
    2. Select "Me" for "Execute the app as:".
    3. Select "Anyone, even anonymous" for "Who has access to the app:".
      • This setting is for a test situation.
      • You can also access with the access token by setting "Only myself" instead of "Anyone, even anonymous".
    4. Click "Deploy" button as new "Project version".
    5. Automatically open a dialog box of "Authorization required".
      1. Click "Review Permissions".
      2. Select own account.
      3. Click "Advanced" at "This app isn't verified".
      4. Click "Go to ### project name ###(unsafe)"
      5. Click "Allow" button.
    6. Click "OK".
    7. Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
      • When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.

    3. Use Web Apps as an API:

    The following script is for PHP. Please set the query parameter of id and index. id is the Google Document ID. When index=1 is set, the horizontal rule is inserted to the top of body in Document. In this case, index means each row in the Google Document.

    $url = 'https://script.google.com/macros/s/###/exec?id=###&index=1';
    $curl = curl_init();
    $option = [
      CURLOPT_URL => $url,
      CURLOPT_CUSTOMREQUEST => 'GET',
      CURLOPT_FOLLOWLOCATION => true,
    ];
    curl_setopt_array($curl, $option);
    $response = curl_exec($curl);
    $result = json_decode($response, true);
    curl_close($curl);
    

    Pattern 2:

    I think that your proposal of I'm also going to look at possible inserting a thin table with a top border line as a replacement for a horizontal rule. can be also used as the workaround. For achieving this, the script is as follows.

    When this script is run, new table that has the line of only top is created to the top of document. Before you run the script, please set $documentId. In this case, please set Google_Service_Docs::DOCUMENTS to the scopes.

    Sample script:

    $documentId = '###';
    $index = 1;
    $style = [
        'width' => ['magnitude' => 0, 'unit' => 'PT'],
        'dashStyle' => 'SOLID',
        'color' => ['color' => ['rgbColor' => ['blue' => 1, 'green' => 1, 'red' => 1]]]
    ];
    $requests = [
        new Google_Service_Docs_Request([
            'insertTable' => [
                'location' => ['index' => $index],
                'columns' => 1,
                'rows' => 1
            ]
        ]),
        new Google_Service_Docs_Request([
            'updateTableCellStyle' => [
                'tableCellStyle' => [
                    'borderBottom' => $style,
                    'borderLeft' => $style,
                    'borderRight' => $style,
                ],
                'tableStartLocation' => ['index' => $index + 1],
                'fields' => 'borderBottom,borderLeft,borderRight'
            ]
        ])
    ];
    $batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest([
      'requests' => $requests
    ]);
    $result = $service->documents->batchUpdate($documentId, $batchUpdateRequest);
    

    References: