---
title: "Extract text from DOCX, XLSX and PPTX in C#"
url: https://recursiveai.org/onedocument/cookbook/extract-text-from-office-files/
description: "Extract Office text with one API. XLSX returns string cells, not numeric values."
version: "1.0.0"
---

Extract Office text with one API. XLSX returns string cells, not numeric values.

```shell
dotnet add package RecursiveAI.OneDocument.Documents
dotnet add package RecursiveAI.OneDocument.Spreadsheets
dotnet add package RecursiveAI.OneDocument.Presentations
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneDocument;
using RecursiveAI.OneDocument.Documents;
using RecursiveAI.OneDocument.Spreadsheets;
using RecursiveAI.OneDocument.Presentations;

foreach (string path in new[] {
    "invoice.docx", "sales.xlsx", "review.pptx" })
{
    Console.WriteLine($"--- {path} ---");
    Console.WriteLine(Office.ExtractText(path).Trim());
}
```

The three inputs are in the zip. Prints their text, as shown below.

Unzip [the example](https://recursiveai.org/onedocument/cookbook/extract-text-from-office-files/extract-text-from-office-files.zip), then `dotnet run`.

## Full program

All three inputs are included in the example. `invoice.docx` contains “Invoice for Northwind: 120 EUR.”; `sales.xlsx` has headers `Region`, `Sales` and a row with text `North` and numeric value `120`; `review.pptx` has title “Quarterly review” and subtitle “Sales: 120 EUR”.

The download’s `Program.cs` is the snippet above.

`dotnet run` prints:

```text
--- invoice.docx ---
Invoice for Northwind: 120 EUR.
--- sales.xlsx ---
Region	Sales
North
--- review.pptx ---
Quarterly review
Sales: 120 EUR
```

Damage in the main XML part raises `OfficeFormatException`; a missing or damaged secondary part is reported through `OpenContext.Defects` and extraction continues.

## Variations

### Write directly to a text file

Keep the full program’s using lines and replace its loop with:

```csharp
using var writer = File.CreateText("invoice.txt");
Office.ExtractText("invoice.docx", writer);
Console.WriteLine("Wrote invoice.txt");
```

Output:

```text
Wrote invoice.txt
```

## Related recipes

- [Find and replace text in a Word document in C#](https://recursiveai.org/onedocument/cookbook/find-and-replace-in-word/)
- [Convert PowerPoint to PDF in C#](https://recursiveai.org/onedocument/cookbook/convert-pptx-to-pdf/)
- [Fill a Word template in C#](https://recursiveai.org/onedocument/cookbook/fill-word-template/)
- [Mail merge DOCX files in C#](https://recursiveai.org/onedocument/cookbook/mail-merge/)

## The short answer

Use `Office.ExtractText(path)` after referencing the packages for the formats you read. The same call handles DOCX, XLSX and PPTX. The complete program prints a heading and extracted text for each original sample file, so you can see the different output shapes together.

This is text extraction, not page rendering or OCR. In particular, a numeric Excel cell is not a text cell. The sample deliberately includes the number 120 in `sales.xlsx`: it is absent from the extracted text even though the string `120 EUR` appears in the presentation and document. If you need numeric cell values, use the workbook model in [Read an Excel file in C#](https://recursiveai.org/onedocument/cookbook/read-excel-file/) rather than this text-only path.

## How do I extract text from DOCX, XLSX and PPTX in C#?

Install the documents, spreadsheets and presentations packages in a .NET 10 project. Each registers its format support. Pass a file path to `Office.ExtractText`; the format registry reaches the appropriate extraction path. You can combine different file types in a single loop, as in the example, without branching on the extension for every file.

For OOXML files the extractor streams the text-bearing package parts instead of building the full document model. It holds paragraph buffers and, for workbooks, the shared string table. This is useful when you want searchable text rather than editable paragraph, cell or shape objects. It does not preserve the appearance or exact geometry of a page.

Word paragraphs end with line feeds. Tabs and manual line breaks become corresponding text characters. Table rows appear on lines with tab-separated cells; paragraphs inside a cell become spaces. Field results are included, but field instruction text is not. By default the extraction also includes headers, footers, notes and comments after the body, with blank lines separating parts. Those are sensible search inputs, but they are not necessarily the order in which a person visually scans a page.

PowerPoint extraction follows slide order, then shape order within the stored slide markup. Each slide’s speaker notes follow it by default. Slide-number placeholders and notes-page slide images are skipped. This can make the extracted text longer than the visible slide text without indicating a duplicate slide.

For the exact rules and configurable options, see [text extraction](https://recursiveai.org/onedocument/docs/text-extraction/). In Word, inserted and moved-to text is included while deleted and moved-from text is left out by default. That distinction matters when indexing documents that still contain tracked revisions.

## How do I extract Office text to a file for free?

Yes: MIT or Apache-2.0, free for commercial use.

The variation passes a `TextWriter` directly to `Office.ExtractText`. It writes `invoice.txt` instead of returning one large string for the caller to save. Use one writer per destination, dispose it after extraction, and keep input and output paths separate. The example requires no online extraction account.

Workbook extraction returns strings in sheet and row order. Shared strings, inline strings and cached formula string results are included. Numbers, booleans and errors have no text of their own in this output. Formatted dates and amounts therefore require the spreadsheet model and its number-format handling. Renaming an XLSX file or treating missing numbers as empty strings won’t turn this API into a table export.

Finally, plan for partial output when using a writer. Damage in the main part raises `OfficeFormatException`, and text already written stays written. Missing or damaged secondary parts are reported through `OpenContext.Defects` while extraction continues. For an indexing workflow, keep diagnostics with the extracted text so that a partially readable file is not confused with a truly empty document.
