Edit Slide (PowerPoint for Google) with Python (Low-cost RPA case with Google API and Python)

Introduction

How often do you have the opportunity to create presentations on Google Slides and PowerPoint? It is expected that many people spend a lot of time in their work.

If you can operate presentation materials that take a lot of time with Python, and if you can edit and update the presentation contents automatically, it will surely lead to business efficiency. In addition, Google Slide can be converted to ppt format and downloaded as Power Point. Now let's operate Google Slide with popular Python.

Overview

In this article, we will publish a Python Class for "reading / writing / erasing" the title and body of Slide in Google Drive. An example of using to edit the Table in Slide will be explained in another article.

This article was originally based on the Google API Reference, and this time I will present an example of defining, instantiating, and using a Class.

You can edit multiple Slides at the same time by instantiating, so please give it a try. Also, Class is just an example, so if you are interested, please customize it yourself.

Premise

--In this article, I use Jupyter Notebook to draw a table in Pandas Dataframe for visual clarity. However, it can also be used with regular Py files. --Please do the following article so that you can authenticate to Google Slides API from Python --Download token.pickle from the official URL below and rename it to "slide_token.pickle" - https://developers.google.com/slides/quickstart/python ――If you want to check how to download the above token with explanation, please refer to the following URL. - https://qiita.com/ken0078/items/ece6fe2a871446383481

procedure

** 1. Prepare the following Slide ** (The first page) スクリーンショット 2020-02-22 22.57.51.png (2nd page) スクリーンショット 2020-02-22 22.58.23.png

** 2. Create ipynb with Jupyter Notebook, copy and execute the following Class / Def to the step **

View code

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

class SlidesApi:

    def __init__(self,PRESENTATION_ID):
        self.presentation_id = PRESENTATION_ID
        self.service = self.launch_api()
        self.read_slides()
        self.get_elements()

    def launch_api(self):
        SCOPES = ['https://www.googleapis.com/auth/presentations']

        creds = None
        if os.path.exists('slede_token.pickle'):
            with open('slede_token.pickle', 'rb') as token:
                creds = pickle.load(token)

        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                creds = flow.run_local_server(port=0)
            with open('slede_token.pickle', 'wb') as token:
                pickle.dump(creds, token)

        service = build('slides', 'v1', credentials=creds)

        return service

    def read_slides(self):
        presentation = self.service.presentations().get(presentationId=self.presentation_id).execute()
        self.slides = presentation.get('slides')

    def get_elements(self):
        self.read_slides()
        self.page_element_list = []

        for page_num in range(0,len(self.slides),1):
            for element in  self.slides[page_num]['pageElements']:
                if "shape" in  list(element.keys()):
                    self.page_element_list.append({"page": page_num,"type":element['shape']['placeholder']['type'],\
                                    "objectId":element['objectId'],"contents":extract_text_from_shape(element['shape'])})

                elif "table" in  list(element.keys()):
                    self.page_element_list.append({"page": page_num,"type":"TABLE",\
                                "objectId":element['objectId'],"contents":extract_text_from_table(element['table'])})

        return self.page_element_list
    


    def find_shape_by_page(self,find_type,find_page):
        self.result_shape = []
        
        for lst in self.page_element_list:
            if (lst['page'] == find_page) and (lst['type'] == find_type):
                self.result_shape.append(lst)
    
        return self.result_shape

    def get_shape(self,find_type,find_page = None,find_title = None):
        self.result_shape = []

        if find_page is not None:
            self.result_shape= self.find_shape_by_page(find_type,find_page)
        
        elif find_title is not None:
            page_num = None
            
            for lst in self.page_element_list:
                if (find_title in lst['contents'][0]) and (lst['type'] == find_type):
                    page_num = lst['page']
            
            if page_num is not None:
                self.result_shape = self.find_shape_by_page(find_type,page_num)
                    
        return self.result_shape
    
    

    def clear_shape_contents(self,objectId):
        requests = []
            
        requests.append({
            "deleteText": {
                "objectId": objectId,
                "textRange": {
                "type": "ALL",
                }
            }
            })
            
        try:
            body={'requests':requests}
            response=self.service.presentations().batchUpdate(presentationId=self.presentation_id, body=body).execute()
            self.read_slides()
            self.get_elements()
            print("Result: Clear the contents successfully")
        except:
            print("Exception: Failed to clear contents in the table ")
            


    def writes_text_to_shape(self,objectId,text,default_index = 0):
        requests = []
        
        requests.append({
            "insertText": {
                "objectId": objectId,
                "text": text,
                "insertionIndex": default_index
            }})        
        try:
            body={'requests':requests}
            response= self.service.presentations().batchUpdate(presentationId=self.presentation_id, body=body).execute()
            self.read_slides()
            self.get_elements()
        except:
            print("Exception: Failed to add contents to the table ")
    

def extract_text_from_shape(element_dict):

    text_box = []
    if "text" not in list(element_dict.keys()):
        pass
    else:
        element_dict['text']['textElements']
        for lst in element_dict['text']['textElements']:
            if "textRun" in list(lst.keys()):
                text_box.append(lst["textRun"]['content'])
    
    return text_box


** 3. Based on the defined Class, create an instance with the Slide ID in 1. in the previous section as an argument **

#PRESENTATION_Enter ID as an argument to ID(str)
test_slides = SlidesApi(PRESENTATION_ID='XXXXXXXXXXX') 

At the same time as creating this instance, the list of Elements (title / body / table, etc.) of all sheets will be extracted from Slide.

** 4. Check the list of Elements obtained from Slide with print **

print(test_slides.page_element_list)
#Output result
[{'type': 'CENTERED_TITLE', 'objectId': 'i0', 'page': 0, 'contents': ['Page1 Sample Tiltle\n']}, {'type': 'SUBTITLE', 'objectId': 'i1', 'page': 0, 'contents': ['Page1 Sample Subtitle\n']}, {'type': 'TITLE', 'objectId': 'g600b545905_0_1', 'page': 1, 'contents': ['Page2 Sample Title\n']}, {'type': 'BODY', 'objectId': 'g600b545905_0_2', 'page': 1, 'contents': ['Page2 body description 1\n', 'Page2 body description 2\n', 'Page2 body description 3\n', '\n']}, {'type': 'TABLE', 'objectId': 'g634fca277e_0_0', 'page': 1, 'contents': [['a\n', 'a\n', 'a\n'], ['a\n', 'a\n', 'a\n'], ['a\n', 'a\n', 'a\n'], ['a\n', 'a\n', 'a\n']]}, {'type': 'TABLE', 'objectId': 'g294209d42ab89e2c_1', 'page': 1, 'contents': [['b\n', 'b\n', 'b\n'], ['b\n', 'b\n', 'b\n'], ['b\n', 'b\n', 'b\n'], ['b\n', 'b\n', 'b\n']]}, {'type': 'TITLE', 'objectId': 'g600b545905_0_6', 'page': 2, 'contents': ['Page3 Sample Title\n']}, {'type': 'BODY', 'objectId': 'g600b545905_0_7', 'page': 2, 'contents': ['Page3 body description 1\n']}]

This is hard to understand, so let's convert it with Pandas

** 5. Convert the Python List in step 4 to Pandas Dataframe and check the read value **

Do the following:

import pandas as pd
df = pd.DataFrame(test_slides.page_element_list)
df.loc[:, ['page', 'type', 'objectId', 'contents']]

image.png

All the Elements that make up the Slide are listed. However, please note that due to the nature of the API, the Page index starts from 0 instead of 1.

Also, as you may know if you are familiar with Slide's master function, Slide's Element has the following main attributes.

Please refer to the page image given in step 1 to determine which Element has which attribute.

** 6. Use the method to erase the body (BODY) of the second page **

Let's delete the body (BODY) of the second page using the method of the instance. According to the extraction result table, the ID of the body (BODY) of the second page (page1) is "g600b545905_0_2".

image.png

Do the following:

test_slides.clear_shape_contents('g600b545905_0_2')

** 7. Check if the value erasure is reflected ** When I check the slide, it says "Click to add text" and the text disappears.

スクリーンショット 2020-02-22 23.31.51.png

** Write the content of the text on page 8.2 **

Write a new value in the erased body (BODY) on the second page. Write "sample change" using the following method.

test_slides.writes_text_to_shape(objectId = 'g600b545905_0_2',text = "sample change" ,default_index = 0)

** Check the written text on page 9.2 ** When you check the Slide, it says "sample change".

スクリーンショット 2020-02-22 23.35.43.png

Recommended Posts

Edit Slide (PowerPoint for Google) with Python (Low-cost RPA case with Google API and Python)
Edit Google Spread Sheets with Python (Low-cost RPA case with Google APIs and Python)
How to use Service Account OAuth and API with Google API Client for python
Get data from analytics API with Google API Client for python
Low Cost RPA with Google APIs and Python -Post Table Data to Slides: Use Case Overview-
Google Cloud Vision API sample for python
Create and edit spreadsheets in any folder on Google Drive with python
Data acquisition from analytics API with Google API Client for python Part 2 Web application
Causal reasoning and causal search with Python (for beginners)
Try running Google Chrome with Python and Selenium
Display Google Maps API with Rails and pin display
Tweet (API 1.1) on Google App Engine for Python
Get Gmail subject and body with Python and Gmail API
Automate background removal for the latest portraits in a directory with Python and API
Build API server for checking the operation of front implementation with python3 and Flask
[GCP] [Python] Deploy API serverless with Google Cloud Functions!
Benchmark for C, Java and Python with prime factorization
Automatic follow on Twitter with python and selenium! (RPA)
Crawling with Python and Twitter API 1-Simple search function
Book registration easily with Google Books API and Rails
PIL with Python on Windows 8 (for Google App Engine)
Getting Started with Google App Engine for Python & PHP
Speech transcription procedure using Python and Google Cloud Speech API
[Python] Get user information and article information with Qiita API
Install tweepy with pip and use it for API 1.1
Have Google Text-to-Speech create audio data (narration) for video material (with C # and Python samples)
Easy to use Nifty Cloud API with botocore and python
Try hitting the Twitter API quickly and easily with Python
[Python] GUI for inserting TeX format into PowerPoint with 2 clicks [PowerPoint]
I tried follow management with Twitter API and Python (easy)
Installation procedure for Python and Ansible with a specific version
(For myself) Flask_8 (Add / Edit / Delete in database with python)
Analyze stocks with python and look for favorable trading phases
Library for specifying a name server and dig with python
Issue reverse geocoding in Japanese with Python Google Maps API
This and that for using Step Functions with CDK + Python
Play with YouTube Data API v3 using Google API Python Client
Python: Extract file information from shared drive with Google Drive API
Programming with Python and Tkinter
Encryption and decryption with Python
Use Trello API with python
Python and hardware-Using RS232C with Python-
Use Twitter API with Python
Study Python with Google Colaboratory
Web API with Python + Falcon
Play RocketChat with API / Python
Call the API with python3.
Access Google Drive with Python
Google Drive Api Tips (Python)
Works with Python and R
Operate Jupyter with REST API to extract and save Python code
Create AtCoder Contest appointments on Google Calendar with Python and GAS
Get conversions and revenue with Google Analytics API and report to Slack
Create a striped illusion with gamma correction for Python3 and openCV3
Crawling with Python and Twitter API 2-Implementation of user search function
Firebase Authentication token issuance in Python and token verification with Fast API
LINE BOT (Messaging API) development with API Gateway and Lambda (Python) [Part 2]