
I tried translating an entire PowerPoint file using the Google Cloud Translation API
This page has been translated by machine translation. View original
Hi, I'm Keema.
There are situations where you want to translate proposal materials and slides created in PowerPoint into another language while preserving the layout.
A typical requirement is to convert a presentation with shapes, flow diagrams, and charts into English without breaking the visual appearance.
However, if you extract only the text from the slides for translation, the shape placement and flow diagrams fall apart.
Furthermore, unique proper nouns such as product names and character names often need to be consistently translated the same way every time.
Previously, I wrote an article about translating PDFs using the Document Translation feature of Google Cloud's Cloud Translation API.
This feature supports not only PDFs, but also Word, Excel, and PowerPoint.
In this article, I used the same feature to translate a PowerPoint (PPTX) file as-is, and verified in practice how shapes, text boxes, and speaker notes are handled, and whether a glossary can lock in custom terminology.
This article is the PowerPoint edition of a series that verifies document translation by format.
Specifications and behavior were confirmed against Google Cloud's official documentation, with relevant sections cited.
I then ran actual tests to verify whether things work as the official documentation describes.
Series Articles
| Format | Article |
|---|---|
| PDF Edition | Cloud Translation API で PDF をレイアウトを保ったまま翻訳する |
| Word Edition | Cloud Translation API で Word をレイアウトを保ったまま翻訳する |
| Excel Edition | Cloud Translation API で Excel をレイアウトを保ったまま翻訳する |
| PowerPoint Edition (this article) | - |
Target audience: Those considering automating the translation of PowerPoint materials
1. Conclusion: Official Documentation vs. Verified Results
For those who want to get to the point quickly, here is a summary of what the Google Cloud official documentation says about translating PowerPoint (PPTX) files, along with the results I confirmed by actually running translations.
Detailed steps and before/after images are in §3 and later.
| Aspect | Official Documentation | Verified Results (confirmed in this article) |
|---|---|---|
| Titles, bullet points, tables, layout | Translates while preserving format and layout | Preserved and translated |
| Content inside shapes and text boxes | (Word is explicitly stated as "not translated." PPTX is not explicitly stated.) | Was translated |
| Speaker notes | (Not explicitly stated) | Was translated |
| Charts and images | (Not explicitly stated) | Charts (title, axes, legend, categories) and images pasted as pictures remained in Japanese |
| Glossary (locking custom terminology) | Translation can be locked with a glossary | Applied consistently across the entire slide, including titles, bullet points, tables, shapes, text boxes, and speaker notes |
The big difference from Word and Excel is that content inside shapes and text boxes is also translated.
In addition, speaker notes, which are unique to PowerPoint, are also translated, and the glossary is applied consistently to all of these.
For those in a hurry, this table and the images in §4 should give you an overview.
As the final installment of the series, §8 contains a table summarizing the differences across all three formats.
2. What Is Document Translation in Cloud Translation API?
Cloud Translation API's Document Translation is a feature that, when you pass a file directly to it, translates it while preserving the formatting and layout.
It supports DOCX, PPTX, XLSX, and PDF.
An overview of the feature, authentication, and how to create a glossary were covered in previous articles.
Cited from: DevelopersIO: Cloud Translation API で PDF をレイアウトを保ったまま翻訳する
The key thing I wanted to verify for PowerPoint is how shapes and text boxes are handled.
In Word and Excel, the content inside text boxes and shapes was not translated, but since shapes are a primary building block in PowerPoint, I wanted to verify whether the behavior changes.
3. Preparation for Verification
3.1 Prerequisites
The prerequisites are the same as in the Word and Excel editions (macOS, Python 3.12 venv, google-cloud-translate 3.26.0, a personal project with billing enabled).
The steps for enabling the API, ADC authentication, and installing libraries into the venv are also the same.
3.2 Sample Document (Original Fictional Anime)
For verification purposes, I had Claude create a PowerPoint slide deck in the form of an introduction to a fictional anime called "Hoshirei Monogatari: Lumina Chronicle."
It shares the same world setting as the PDF, Word, and Excel editions, with the same proper nouns (coined terms).
The content is completely original and has no relation to any real works, people, or organizations.
The slide deck consists of 7 slides and is packed with verification elements unique to PowerPoint.
- Title, bullet points, tables
- A flow diagram titled "Steps of Reso-Evolution" made with rounded rectangle shapes and arrows
- Text placed inside shapes of various forms: ellipses, hexagons, stars, callouts, arrows, and clouds
- A text box (note) on the world-setting slide
- A bar chart imported from Excel (embedded chart)
- Speaker notes (presenter's notes) on each slide
The PowerPoint translated this time has a total of 7 slides.
All slides before translation are shown below.

Pre-translation PowerPoint slide 1: Title and subtitle, key visual image

Pre-translation PowerPoint slide 2: Bullet-point world setting, text box (note), chart image

Pre-translation PowerPoint slide 3: Table for the Hoshirei Codex

Pre-translation PowerPoint slide 4: Flow diagram titled "Steps of Reso-Evolution" made with rounded rectangle shapes and arrows

Pre-translation PowerPoint slide 5: Bar chart of popularity ranking (embedded chart)

Pre-translation PowerPoint slide 6: Text placed inside shapes of various forms: ellipses, hexagons, stars, callouts, arrows, and clouds

Pre-translation PowerPoint slide 7: Summary cards (rounded rectangle shapes) and text boxes
4. Translating a PowerPoint (PPTX) File
The script used for translation is the same one from the Word edition. Since it determines the MIME type from the file extension, it works just by changing the input to a PPTX file.
The full script is reproduced here so the article stands on its own.
Full text of translate_document_handson.py (click to expand)
from __future__ import annotations
import argparse
import time
from pathlib import Path
from google.cloud import translate_v3 as translate
# Glossaries and custom models must be placed in us-central1.
DEFAULT_LOCATION = "us-central1"
# Extension → MIME type (supported formats for Document Translation)
MIME_BY_SUFFIX = {
".pdf": "application/pdf",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}
def mime_for(path: str) -> str:
"""Returns the MIME type from the input file's extension. Raises ValueError for unsupported extensions."""
suffix = Path(path).suffix.lower()
if suffix not in MIME_BY_SUFFIX:
raise ValueError(f"Unsupported extension: {suffix} (supported: {', '.join(MIME_BY_SUFFIX)})")
return MIME_BY_SUFFIX[suffix]
def parse_args() -> argparse.Namespace:
p = argparse.ArgumentParser(description="Cloud Translation API document translation (synchronous)")
p.add_argument("--project", required=True, help="GCP project ID")
p.add_argument("--input", required=True, help="Input file path")
p.add_argument("--output", required=True, help="Output file path (result without glossary)")
p.add_argument("--source", default="ja", help="Source language code (default: ja)")
p.add_argument("--target", default="en", help="Target language code (default: en)")
p.add_argument("--location", default=DEFAULT_LOCATION, help=f"Location (default: {DEFAULT_LOCATION})")
p.add_argument("--glossary-id", default=None, help="Glossary ID (when specified, outputs both with and without glossary)")
return p.parse_args()
def build_request(args: argparse.Namespace, content: bytes) -> dict:
"""Builds the request dictionary for translate_document.
Specifying the source language is required when using a glossary (per official spec).
"""
parent = f"projects/{args.project}/locations/{args.location}"
mime_type = mime_for(args.input)
request: dict = {
"parent": parent,
"source_language_code": args.source,
"target_language_code": args.target,
"document_input_config": {"content": content, "mime_type": mime_type},
}
if args.glossary_id:
glossary_path = (
f"projects/{args.project}/locations/{args.location}"
f"/glossaries/{args.glossary_id}"
)
request["glossary_config"] = translate.TranslateTextGlossaryConfig(glossary=glossary_path)
return request
def write_bytes(path: str, data: bytes) -> None:
Path(path).parent.mkdir(parents=True, exist_ok=True)
Path(path).write_bytes(data)
def main() -> None:
args = parse_args()
content = Path(args.input).read_bytes()
print(f"Input: {args.input} ({len(content):,} bytes, {args.source}→{args.target})")
client = translate.TranslationServiceClient()
request = build_request(args, content)
started = time.perf_counter()
response = client.translate_document(request=request)
elapsed = time.perf_counter() - started
base = response.document_translation
write_bytes(args.output, base.byte_stream_outputs[0])
print(f"Processing time: {elapsed:.2f} seconds")
print(f"Output (no glossary): {args.output} ({len(base.byte_stream_outputs[0]):,} bytes)")
# With glossary: a single call returns a separate glossary_document_translation output
if args.glossary_id and response.glossary_document_translation.byte_stream_outputs:
out = Path(args.output)
glossary_out = str(out.with_name(f"{out.stem}_glossary{out.suffix}"))
write_bytes(glossary_out, response.glossary_document_translation.byte_stream_outputs[0])
print(f"Output (with glossary): {glossary_out}")
if __name__ == "__main__":
main()
First, translate without a glossary.
python translate_document_handson.py \
--project <YOUR_PROJECT_ID> \
--input hoshirei_ja.pptx \
--output hoshirei_en.pptx
# Example output
Input: hoshirei_ja.pptx (146,984 bytes, ja→en)
Processing time: 1.32 seconds
Output (no glossary): hoshirei_en.pptx (138,328 bytes)
After checking the translation, the titles, bullet points, and tables were translated into English, and the layout was preserved.
First, here are the before-and-after comparisons for all 7 slides.

Slide 1: Left is before translation (Japanese), right is after. Title and subtitle are translated into English.

Slide 2: Left is before, right is after. Both the bullet points and the text box (note) on the right are translated.

Slide 3: Left is before, right is after. The table data is translated into English.

Slide 4: Left is before, right is after. In the flow diagram made with rounded rectangle shapes and arrows, the text inside the shapes is also translated.

Slide 5: Left is before, right is after. The chart's title, axes, legend, and categories remain in Japanese.

Slide 6: Left is before, right is after. The text inside shapes of every form—ellipses, hexagons, stars, callouts, arrows, and clouds—is translated.

Slide 7: Left is before, right is after. The text inside the summary cards (rounded rectangle shapes) is also translated.
The biggest difference from Word and Excel was in how shapes and text boxes are handled.
4.1 Content Inside Shapes and Text Boxes Is Also Translated
The "Steps of Reso-Evolution" flow diagram (slide 4) had even the text inside the rounded rectangle shapes translated.
The text placed inside shapes of various forms—ellipses, hexagons, stars, callouts, arrows, and clouds (slide 6)—was also fully translated.
The text box (note) on the world-setting slide (slide 2) and the content inside the summary cards (slide 7) were also translated.
In Word and Excel, the content inside text boxes and shapes was not translated, but in PowerPoint, the content inside shapes and text boxes was translated.
Even within the same Document Translation feature, how shapes are handled is the opposite depending on the format.
4.2 Speaker Notes Are Also Translated
Speaker notes (presenter's notes) were also checked.
The notes on all slides were translated into English.
Notes are a PowerPoint-specific element not found in Word or Excel, but they are treated as translation targets in the same way as body text and shapes.
The glossary is also applied consistently to notes along with the rest of the slide (covered in more detail in §5.3).
4.3 Charts and Images Are Not Translated
Charts and images were not translated, the same as in Excel.
As shown in the comparison images above for the popularity ranking slide (slide 5), the embedded chart's title, axes, legend, and categories all remain in Japanese.
Also, items placed as images—such as the key visual on the title slide (slide 1) or the chart pasted as an image on the world-setting slide (slide 2)—are not translated because the text within them is part of the image.
5. Locking Custom Terminology with a Glossary
I verified whether proper nouns and custom terminology can be locked to specific translations.
To use a glossary, you need to (1) prepare a TSV with the mapping between source terms and translations, (2) upload it to Cloud Storage, and (3) create a glossary resource.
5.1 Prepare the Glossary TSV
The glossary is prepared as a TSV file with the source term (Japanese) and translation (English) listed tab-separated, one per line.
No header row is needed; the left column is the coined source term and the right column is the fixed translation you want.
For this test, I prepared 20 coined terms from the sample as glossary_ja_en.tsv.
星霊 Hoshirei
共鳴進化 Reso-Evolution
輝光石 Lumina Shard
雷狼ボルテ Voltefang
焔狐ココ Pyrofox Coco
水亀アクオ Aquortle
草鹿リーフィ Leafawn
輝竜ルミナ Lumidragon
月読の祠 Moonread Shrine
守護者 Warden
星導士 Starwright
星霊守護協会 Hoshirei Warden Guild
共鳴値 Reso-Value
共鳴の灯 Resonance Flame
絆ゲージ Bond Gauge
星霊酔い Hoshirei-sickness
星霊図鑑 Hoshirei Codex
ルミナ群島 Lumina Archipelago
七つの祠 Seven Shrines
共鳴結界 Reso-Barrier
5.2 Upload the TSV to Cloud Storage and Create a Glossary Resource
Rather than uploading the TSV directly to create a glossary resource, you first place it in Cloud Storage and then create the resource by specifying that GCS URI.
Create the bucket in the same us-central1 location as the glossary.
# Create bucket (skip if it already exists)
gcloud storage buckets create gs://<YOUR_BUCKET> \
--project <YOUR_PROJECT_ID> --location us-central1
# Upload TSV
gcloud storage cp glossary_ja_en.tsv \
gs://<YOUR_BUCKET>/glossaries/glossary_ja_en.tsv
Next, create the glossary resource from the uploaded TSV.
Creation is a long-running operation (LRO), so run it from the client library and wait for it to complete.
Save the following code as setup_glossary.py and run it within the venv.
Full text of setup_glossary.py (click to expand)
from google.cloud import translate_v3 as translate
PROJECT_ID = "<YOUR_PROJECT_ID>"
LOCATION = "us-central1" # Glossaries are only supported in us-central1
GLOSSARY_ID = "hoshirei-ja-en"
INPUT_URI = "gs://<YOUR_BUCKET>/glossaries/glossary_ja_en.tsv"
client = translate.TranslationServiceClient()
name = client.glossary_path(PROJECT_ID, LOCATION, GLOSSARY_ID)
glossary = translate.Glossary(
name=name,
# Unidirectional (ja→en) glossary
language_pair=translate.Glossary.LanguageCodePair(
source_language_code="ja", target_language_code="en"
),
input_config=translate.GlossaryInputConfig(
gcs_source=translate.GcsSource(input_uri=INPUT_URI)
),
)
parent = f"projects/{PROJECT_ID}/locations/{LOCATION}"
operation = client.create_glossary(parent=parent, glossary=glossary)
result = operation.result(180) # Wait up to 180 seconds for completion
print(f"Creation complete: {result.name} (entry count: {result.entry_count})")
python setup_glossary.py
# Example output
Creation complete: projects/.../locations/us-central1/glossaries/hoshirei-ja-en (entry count: 20)
The official documentation also explicitly states that custom resources must use us-central1.
Note: All of your resources in a single request to Cloud Translation - Advanced must have the same location. Currently, only global and us-central1 locations are supported. For all custom resources—AutoML models, glossaries, long-running-operations—you must use us-central1.
Cited from: Official documentation: Migrate to Cloud Translation - Advanced (v3) | Google Cloud
5.3 Comparing With and Without the Glossary
Translate with the glossary specified.
Passing the glossary ID created in 5.2 to --glossary-id returns both a "without glossary" and "with glossary" result in a single response.
The fixed translations in the following translation results and speaker notes—such as 星霊 becoming Hoshirei and 星導士 becoming Starwright—correspond to these registered entries.
python translate_document_handson.py \
--project <YOUR_PROJECT_ID> \
--input hoshirei_ja.pptx \
--output hoshirei_en.pptx \
--glossary-id <YOUR_GLOSSARY_ID>
Looking at the results without a glossary first, the translations of proper nouns were inconsistent (per Claude's analysis).
Counting the translations of 星霊, which appears 16 times in the source (including speaker notes), without a glossary, the main translation variants were as follows:
Translation of 星霊 (without glossary) |
Occurrences |
|---|---|
| Star Spirit | 6 |
| Star Spirits | 4 |
| star spirit | 2 |
| Celestial Spirit | 2 |
| star spirits | 1 |
| Other variants | Several |
The same word was split across multiple variants, including differences in capitalization and singular/plural forms.
Switching to the glossary version, this was neatly unified.
The title slide is where the translation visibly changed.

Left is without glossary (title reads "Star Spirit Story"), right is with glossary ("Hoshirei Story"—星霊 is locked to Hoshirei)
With the glossary, 星霊 was fixed to Hoshirei, 守護者 to Warden, 共鳴進化 to Reso-Evolution, and 輝光石 to Lumina Shard, exactly as registered.
The glossary was applied consistently across the entire slide—titles, bullet points, tables, shapes and text box content, and even speaker notes.
For example, 星導士 in the speaker notes was translated as Star Guide (a literal translation) without the glossary, but was fixed to Starwright with the glossary.
After checking the full output with the glossary, all registered coined terms were consistently fixed to their registered translations in the PowerPoint (per Claude's analysis).
In the Word edition, one instance of 星霊 was missed, but in this PowerPoint sample, no remaining literal translations were found.
However, occasional misses can happen depending on context, so it is worth noting that even with a glossary, 100% coverage cannot be guaranteed.
6. Pricing and Processing Time
The pricing for document translation varies depending on the translation model used.
For the standard NMT model, document translation is charged per page, and in PowerPoint, each slide counts as a page.
| Item | Unit Price |
|---|---|
| NMT document translation | $0.08 / page |
Cited from: Pricing page: Pricing | Google Cloud
The cost for this sample (7 slides), including both the with-glossary and without-glossary runs, was well under $1.
The processing time was approximately 1–2 seconds in practice.
7. About the Attribution Notice ("Machine Translated by Google")
In the PDF edition, "Machine Translated by Google" appeared in the upper left of the translated PDF.
For this PowerPoint (PPTX), even without explicitly specifying attribution, this notice was not visible in the translated file (the same was true for Word and Excel).
Since the presence or absence of this notice differed between PDF and Office formats under the same conditions, I checked the specification.
The attribution text can be specified as customizedAttribution in the API request, and the default when not specified is "Machine Translated by Google."
This field is not PDF-specific; it is common to translateDocument (document translation) as a whole.
customizedAttribution
stringOptional. This flag is to support user customized attribution. If not provided, the default is Machine Translated by Google. Customized attribution should follow rules in https://cloud.google.com/translate/attribution#attribution_and_logos
Cited from: API reference: Method: projects.locations.translateDocument | Google Cloud
What is important to note here is that customizedAttribution only describes the attribution text itself—there is no explicit statement in the official documentation about how or whether that text is reflected in the output of each format (i.e., whether it is baked into the file).
The reason why the presence of the attribution notice differs by format could not be confirmed from official sources.
Within the scope of my testing, the attribution notice was baked into the PDF output (confirmed with a native PDF in the PDF edition) but was not included in Office format outputs (DOCX/XLSX/PPTX).
My assumption is that this is because PDF output reconstructs the translated text overlaid on the page to preserve the layout—a fundamentally different output construction process from editable Office formats—but this is not backed by official documentation.
Another important point on a separate axis is the explicit obligation under the brand guidelines.
This is separate from whether the notice is "baked into the output file": it requires that when you show translation results to users, regardless of format, you make it clear that the content is machine-translated.
Whenever you display translation results from Google Translate directly to users, you must make it clear to users that they are viewing automatic translations from Google Translate using the appropriate text or brand elements.
Cited from: Brand guidelines: Attribution requirements | Google Cloud
In other words, the fact that the attribution notice is not baked into the Office format output is not itself a problem, but when publishing or distributing translation results, regardless of format, it is the user's responsibility to make it clear that the content is machine-translated.
8. Summary (Comparison Across the Series)
PowerPoint (PPTX) translates not only titles, bullet points, and tables, but also the content inside shapes and text boxes as well as speaker notes, and the glossary is applied consistently to all of these.
What is not translated are charts (embedded charts) and figures pasted as images.
Here is a summary table of the differences discovered by translating all three formats—Word, Excel, and PowerPoint—throughout this series.
| Element | Word (DOCX) | Excel (XLSX) | PowerPoint (PPTX) |
|---|---|---|---|
| Body text, tables, data | Translated | Translated | Translated |
| Content inside text boxes and shapes | Not translated | Not translated | Translated |
| Charts (title, axes, legend) | - | Not translated | Not translated |
| Formulas | - | Preserved and recalculated (string literals inside formulas are not translated) | - |
| Speaker notes | - | - | Translated |
| Glossary | Applied consistently | Applied consistently | Applied consistently |
The biggest difference is in how content inside text boxes and shapes is handled.
In Word and Excel, it is not translated and remains in Japanese, whereas in PowerPoint, it is translated.
Depending on how a document is structured, this affects decisions about where to place text before translation.
- Word/Excel: Place text you want translated in the body text or table cells rather than in text boxes
- PowerPoint: Text placed in shapes or text boxes will be translated. What is not translated are charts and figures pasted as images
It was also common across all formats that charts are not translated.
If you want to translate chart titles or legends, you will need to prepare them separately as text before converting them to a chart image.
Throughout this series, it was confirmed that PDF, Word, Excel, and PowerPoint can all be translated while preserving their layouts, and that custom terminology can be largely locked in with a glossary.
It seems best to understand the format of the document you are working with and how shapes and charts are used, so you can identify any areas that need manual attention before or after translation.
I hope this series is useful for those considering automating the translation of Office documents.