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.