https://txtfetch.com/tools/pptx-to-text/
Your slide deck, as text. No code required.
Drop a real PowerPoint deck below. See every slide's text, and its speaker notes, come out right here, in your browser. Nothing is uploaded. It's the same read txtfetch's API gives you, just local.
Drop a Word, Excel, PowerPoint, or OpenDocument (.odt/.ods/.odp, zipped or flat) file below to see the actual text it extracts to. It runs entirely in your browser, and nothing is uploaded.
Up to 25 MB, read fully in-browser — larger files still work through the API.
What's not in this text:
curl -X POST https://api.txtfetch.com/v1/extract \
-H "Authorization: Bearer $TXTFETCH_KEY" \
-F file=@__FILENAME__import os
import requests
with open("__FILENAME__", "rb") as f:
r = requests.post(
"https://api.txtfetch.com/v1/extract",
headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"},
files={"file": f},
)
print(r.json()["extracted_text"])import { readFile } from "node:fs/promises";
const file = new Blob([await readFile("__FILENAME__")]);
const form = new FormData();
form.append("file", file, "__FILENAME__");
const res = await fetch("https://api.txtfetch.com/v1/extract", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TXTFETCH_KEY}` },
body: form,
});
const { extracted_text } = await res.json();
console.log(extracted_text);package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
type extractResponse struct {
Status string `json:"status"`
ExtractedText string `json:"extracted_text"`
}
func main() {
f, err := os.Open("__FILENAME__")
if err != nil {
panic(err)
}
defer f.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", "__FILENAME__")
if err != nil {
panic(err)
}
if _, err := io.Copy(part, f); err != nil {
panic(err)
}
writer.Close()
req, err := http.NewRequest("POST", "https://api.txtfetch.com/v1/extract", &body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("TXTFETCH_KEY"))
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result extractResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
panic(err)
}
fmt.Println(result.ExtractedText)
}whats-hard-about-pptx
Slide order is defined by ppt/presentation.xml's <p:sldIdLst>, a relationship list. It does not reliably match the slide part filenames' numeric order. slide10.xml can come before slide2.xml in the deck's actual reading order. Trust the filenames and slides silently shuffle.
Speaker notes are a genuinely separate part of the file, ppt/notesSlides/. They link back to their slide through a relationship file, not by sitting near the slide's own XML. An extractor that reads slide bodies and stops never sees them. One built only around notes misses the slide content instead.
Empty placeholders are the opposite problem. PowerPoint templates fill unused title, body, and subtitle boxes with placeholder markup that carries no real text at all. Reading the raw XML structure literally would print blank line after blank line for slides that are mostly template scaffolding. This tool drops paragraphs that produced no text, rather than keeping the noise.
what-to-do-next
Got the text out and want the API call for it directly? The panel above already has it, with your file's real name. Extracting many documents, or files bigger than this browser tool's 25 MB cap? See the full PowerPoint extraction guide (.pptx, .ppt) →
faq
- Does this tool upload my deck anywhere?
- No. Everything happens in your browser using the Web Platform's own DecompressionStream API. The file is read locally and never sent over the network. Only the finished text ever leaves your machine, and only if you choose to copy or download it.
- Does it get the slide order right?
- Yes. Slide order comes from ppt/presentation.xml's own relationship list, not from the slide part filenames. Those filenames don't reliably match reading order; slide10.xml can precede slide2.xml.
- Are speaker notes included?
- Yes, and clearly labelled. Notes live in a separate part of the file from the slide body. This tool reads both, and marks the notes text "Speaker notes:" so it's never confused with what's actually on the slide.
- Why don't empty slides show a bunch of blank lines?
- PowerPoint templates fill unused placeholder boxes with markup that has no real text in it. This tool drops any paragraph that produced no text at all, so template scaffolding doesn't show up as noise in the output.
- Does it read SmartArt diagrams or chart data labels?
- This in-browser tool does not, yet. SmartArt and chart content live in their own separate XML parts this quick check doesn't read. Plain text boxes, titles, and table cells are covered. txtfetch's full API reads more of a deck's structure than this browser demo does.
- Is there a file size limit?
- This tool reads up to 25 MB entirely in your browser. Larger decks, or a batch you want to automate, go through the same extraction via the API, which has no such limit.
That was one file. The API does the queue.
This page read your PPTX on your own machine. The API reads a folder of them.
Read the quickstart →