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.
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.
--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
** 1. Prepare the following Slide ** (The first page) (2nd page)
** 2. Create ipynb with Jupyter Notebook, copy and execute the following Class / Def to the step **
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']]
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".
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.
** 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".
Recommended Posts