Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Created September 25, 2021 02:33
Show Gist options
  • Save tanaikech/f1f9fb91d3432362670c810ae05ba53b to your computer and use it in GitHub Desktop.
Save tanaikech/f1f9fb91d3432362670c810ae05ba53b to your computer and use it in GitHub Desktop.
Replacing Template Texts with Array in Google Document using Docs API with Python

Replacing Template Texts with Array in Google Document using Docs API with Python

This is a sample script for replacing the template texts with an array in Google Document using Docs API with Python.

The sample input and output situations are as follows.

In the current stage, when replaceAllText of Docs API is used with the sample value of ["updated text 1", "updated text 2", "updated text 3"], all values of {{oldText}} are replaced with the 1st value of updated text 1 in one batch request. So in order to replace each {{oldText}} with ["updated text 1", "updated text 2", "updated text 3"], it is required to use a workaround.

Flow:

As a workaround, I would like to propose the following flow.

  1. Search each {{oldText}} in the texts of Google Document.

    • In this case, I used documents.get method.
  2. Add the count to the texts of {{oldText}}. It's like {{oldText1}}, {{oldText2}} and {{oldText3}}.

  3. {{oldText1}}, {{oldText2}} and {{oldText3}} is replaced with each element of ["updated text 1", "updated text 2", "updated text 3"] in order using replaceAllText request.

In this flow, the batchUpdate request is used for one call. The sample script is as follows.

Sample script:

# Please set the values you want to replace.
sample = ["updated text 1", "updated text 2", "updated text 3"]
documentId = '###' # Please set your document ID.


docs = build('docs', 'v1', credentials=creds)
obj = docs.documents().get(documentId=documentId, fields='body').execute()
content = obj.get('body').get('content')
templateTextCount = 0
requests = []
for c in content:
    if 'paragraph' in c:
        p = c.get('paragraph')
        for e in p.get('elements'):
            textRun = e.get('textRun')
            if textRun:
                text = textRun.get('content')
                if '{{oldtext}}' in text:
                    templateTextCount += 1
                    requests.append(
                        {
                            "replaceAllText": {
                                "replaceText": sample[templateTextCount - 1],
                                "containsText": {
                                    "text": '{{oldtext' + str(templateTextCount) + '}}',
                                    "matchCase": True
                                }
                            }
                        }
                    )
                    requests.append({
                        "insertText": {
                            "location": {
                                "index": e['startIndex'] + text.find('{{oldtext}}') + len('{{oldtext')
                            },
                            "text": str(templateTextCount)
                        }})

if requests != []:
    requests.reverse()
    result = docs.documents().batchUpdate(documentId=documentId, body={'requests': requests}).execute()

Note:

  • In this sample script, as the sample for explaining my workaround, the paragraphs in Google Document are searched. For example, when you want to search the texts in the tables, please modify the above script.

  • This sample script supposes that you have already been able to get and put values for Google Document using Docs API. Please be careful this.

  • Of course, this workaround can be also used for other languages.

References:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment