https://txtfetch.com/tools/xlsx-to-text/
Your spreadsheet, as text. No code required.
Drop a real Excel workbook below. Watch every sheet's cells become plain text 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-xlsx
A cell's text usually isn't in the cell. String values in .xlsx are indices into xl/sharedStrings.xml, a dedup table shared by the whole workbook. A cell's raw XML often says nothing more than <v>42</v>, and 42 is a lookup key, not the word it represents. Read the cell in isolation and you get a number pointing at another number.
Formula cells store the formula, not the answer. A cell can hold =SUM(A1:A10) in its <f> element, while the number a person actually sees is a separately cached <v> value written alongside it. Sheet order is defined by xl/workbook.xml's own <sheet> list. That list does not reliably match the worksheet files' numeric filenames. sheet10.xml can come before sheet2.xml in a workbook's real reading order, so trusting filename order silently reshuffles sheets.
Hiding a sheet in Excel doesn't remove its data, either. A lot of naive extraction skips hidden sheets on the assumption that "hidden" means "not part of the workbook." That drops real content. This tool reads hidden sheets too, and just flags them so you know which ones weren't visible in the spreadsheet.
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 Excel extraction guide (.xlsx, .xls) →
faq
- Does this tool upload my spreadsheet 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 sheet order right?
- Yes. Sheet order and names come from xl/workbook.xml's own <sheet> list, not from the worksheet part filenames. Those filenames don't reliably match reading order; sheet10.xml can precede sheet2.xml.
- Do formula cells show the formula or the calculated value?
- The calculated value. This tool reads the cached result Excel stores alongside the formula, the same way txtfetch's API does. So you see 18200, rather than the literal string =SUM(A1:A10).
- Are hidden sheets included?
- Yes, and flagged. Hiding a sheet in Excel doesn't remove its data. So this tool includes hidden sheets in the extracted text, and marks each one "(hidden)". That way you can tell which sheets weren't visible in the workbook.
- Do dates and percentages come back formatted, or as raw numbers?
- As their raw stored value. This in-browser tool doesn't apply Excel's number formats, so a date comes back as its serial number and a percentage as its decimal fraction. txtfetch's full API resolves number formats; this quick browser check doesn't yet.
- Is there a file size limit?
- This tool reads up to 25 MB entirely in your browser. Larger workbooks, 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 XLSX on your own machine. The API reads a folder of them.
Read the quickstart →