Table of Contents

Read text and walk the document

Every node in a WordDocument has GetText(), and the whole tree can be walked with a DomVisitor. Use them for search indexing, validation, or extracting data from documents.

Extract text

using DocWright;
using DocWright.Core.Document;
using DocWright.Dom;

using WordDocument document = converter.Load(File.OpenRead("table-styles.docx"));

// All text, as a reader sees it: tracked changes applied, field results not field codes.
string text = document.GetText();
Console.WriteLine(text.Split('\n')[0]);

// As it was before tracked changes.
string original = document.GetText(RevisionView.Original);

// Paragraph by paragraph, and into tables.
foreach (Section section in document.Sections)
{
    foreach (Block block in section.Blocks)
    {
        if (block is Table table)
        {
            foreach (TableRow row in table.Rows)
            {
                Console.WriteLine(string.Join(" | ", row.Cells.Select(c => c.GetText().Trim())));
            }
        }
    }
}

Output (with the counting example below)

DocWright seed document six: a table with conditional table-style formatting.
Product | Quantity | Status
Widgets | 12 | Shipped
Gadgets | 7 | Pending
Gizmos | 31 | Shipped
Sprockets | 4 | Backordered
16 paragraphs, 0 tables, 2 images

GetText() returns what a reader sees: tracked changes applied, and fields as their results rather than their codes. Pass RevisionView.Original for the text as it was before tracked changes. It works on any node: a document, section, paragraph, table cell, header or footnote.

The document tree

WordDocument
├─ Sections ─ Section
│             ├─ Blocks ─ Paragraph ─ Inlines ─ TextRun, TabChar, BreakChar, ImageRef, FieldChar, …
│             │           Table ─ Rows ─ TableRow ─ Cells ─ TableCell ─ Blocks …
│             │           SdtBlock (content control)
│             └─ (headers and footers are referenced by the section)
├─ HeaderFooters, Footnotes, Endnotes
├─ Styles, Numbering, Theme, Settings

Walk it with a visitor

Derive from DomVisitor and override the nodes you care about. Call base to keep walking into a node's children:

using DocWright.Dom;

using WordDocument letter = converter.Load(File.OpenRead("letterhead.docx"));
var counter = new ContentCounter();
letter.Accept(counter);
Console.WriteLine($"{counter.Paragraphs} paragraphs, {counter.Tables} tables, {counter.Images} images");

Then call document.Accept(visitor), as the sample does. The visitor reaches every node in document order, including table cells and content controls. A visitor that tracks context, such as "which table am I in", is shown in the JSON template tutorial.

Other formats

To save text rather than read it in code, use the plain-text writer: converter.Save(document, stream, ".txt"). See Formats.