OfficeIMO.Reader.Core
3.6.1
Prefix Reserved
dotnet add package OfficeIMO.Reader.Core --version 3.6.1
NuGet\Install-Package OfficeIMO.Reader.Core -Version 3.6.1
<PackageReference Include="OfficeIMO.Reader.Core" Version="3.6.1" />
<PackageVersion Include="OfficeIMO.Reader.Core" Version="3.6.1" />
<PackageReference Include="OfficeIMO.Reader.Core" />
paket add OfficeIMO.Reader.Core --version 3.6.1
#r "nuget: OfficeIMO.Reader.Core, 3.6.1"
#:package OfficeIMO.Reader.Core@3.6.1
#addin nuget:?package=OfficeIMO.Reader.Core&version=3.6.1
#tool nuget:?package=OfficeIMO.Reader.Core&version=3.6.1
OfficeIMO.Reader.Core
OfficeIMO.Reader.Core is the dependency-light contract and orchestration package for OfficeIMO document ingestion.
It contains normalized result models, limits, deterministic routing, handler registration, processing pipelines, and
capability manifests. It does not reference Word, Excel, PowerPoint, PDF, Email, image, or other format engines.
Install
dotnet add package OfficeIMO.Reader.Core
Add only the format packages an application needs:
dotnet add package OfficeIMO.Reader.Word
dotnet add package OfficeIMO.Reader.Email
Use OfficeIMO.Reader.All only when the complete local managed format graph is intentional.
Format handlers can register ReaderHandlerRegistration.ReadDirectoryBundle for directory packages with their exact registered extensions. Reader dispatches these paths as individual documents and excludes their resources from recursive folder ingestion. The handler owns bounded traversal, physical-root validation, cancellation, and snapshot hashing, and must report aggregate physical file bytes in Source.LengthBytes. Reader supplies the effective input-byte limit and verifies the reported size. Capability schema version 7 exposes this support through SupportsDirectoryBundle; ordinary directories retain the folder-ingestion path. Bundle detection reports extension/handler evidence without claiming content inspection.
Build a reader
using OfficeIMO.Reader;
using OfficeIMO.Reader.Word;
OfficeDocumentReader reader = new OfficeDocumentReaderBuilder()
.AddWordHandler()
.WithMaxConcurrentReads(4)
.Build();
OfficeDocumentReadResult document = reader.ReadDocument("Policy.docx");
Use document.EnumerateContent() to walk paragraphs and tables together in source order. Each item exposes
one Block, Table, or fallback Chunk, plus its effective Location. Tables keep their rows together and
use known source positions or an unambiguous block anchor. Content without a known position follows positioned
content in the same page, slide, or sheet. The traversal preserves the source objects; copy values when an
immutable snapshot is needed.
Inspect review and saved content
Enable native inspection on rich document or structured reads:
OfficeDocumentReadResult inspected = reader.ReadDocument("Review.docx", new ReaderOptions {
Inspection = new ReaderInspectionOptions {
MaxRecords = 4096,
MaxCharacters = 1_000_000
}
});
foreach (OfficeDocumentMetadataEntry entry in inspected.Metadata) {
if (entry.Category == OfficeDocumentInspectionCategories.Comment)
Console.WriteLine($"{entry.Value} ({entry.SourceObjectId})");
}
Format owners supply comments and replies, revision text, authored formulas with saved caches, hidden source state, inert package descriptors, and bounded content-safety observations where supported. Located metadata keeps native identifiers and semantic attributes through ExtractStructured, JSON, and nested document results. Coverage entries state the requested flags, selection, native profile, and omissions. Formula inspection reads stored values without recalculation; package and safety observations do not validate signatures or execute content.
Inspection is null by default. Its options are snapshotted, and record/character budgets span nested, folder, and batch reads. Exceeding an inspection or native safety admission ceiling throws terminal ReaderResourceLimitException; ordinary malformed inputs retain the existing recoverable per-file behavior. Unicode and concealment observations are heuristic evidence. See migration guidance for the typed native owner exception.
The six content flags default to true when inspection is enabled: IncludeComments,
IncludeRevisions, IncludeFormulas, IncludeVisibility, IncludePackageContent,
and IncludeContentSafety. Disable individual flags to omit that work. MaxRecords
defaults to 4,096, including coverage records; MaxCharacters defaults to one million
and counts retained names, values and attributes. Both must be positive. These are
inspection-output budgets, not a bound on every allocation made by the format loader.
IncludePackageContent requests original-package structural observations in Word,
Excel and PowerPoint loaders, plus their inert payload/VBA descriptors. The metadata
records its physical source scope and whether that import route captured a report.
Presence of a macro or signature part does not establish execution or signature
validity. Format-specific parser limits and qualified profiles still apply.
Inspection uses the existing document metadata transport and does not introduce a new schema version or a dependency on FileInspectorX. The format owners and Reader adapters remain independently usable; mapping their evidence into another product and selecting that product's package graph are separate integration decisions.
Find content by page
Page-aware reading stays on OfficeDocumentReadResult; it is not a separate conversion path. A format adapter
populates Pages, and Reader Core provides shared location, search, and page-scoped Markdown helpers:
OfficeDocumentSearchResult matches = document.Search("retention period");
foreach (OfficeDocumentSearchHit hit in matches.Hits) {
Console.WriteLine(hit.Block.Text);
foreach (OfficeDocumentPageLocation location in hit.Pages) {
Console.WriteLine(location.Display); // for example: Page 5 of 20
}
}
string pageMarkedMarkdown = document.ToPageMarkedMarkdown();
string text = document.GetText();
IReadOnlyList<OfficeDocumentPageText> pageText = document.GetPageText();
Page boundaries are not equally authoritative in every source format:
| Format | Page provenance | Reader behavior |
|---|---|---|
Native |
Uses fixed pages and source geometry from the PDF logical model. | |
| Word | Computed |
Opt-in best-effort pagination through the OfficeIMO.Word layout engine. |
| RTF | ExplicitBreak |
Opt-in reconstruction from explicit/saved page and section-break hints; automatic overflow is not calculated. |
Use document.GetPageProvenance() when page accuracy affects citations. GetPageMarkdown() returns separate
page values, while ToPageMarkedMarkdown() produces one portable Markdown string with HTML page markers.
GetText() follows the same canonical source order, emits structured table cells separated by tabs,
and avoids duplicate block, chunk and table projections. GetPageText() returns only observed page-like
containers, with their original page metadata and provenance. These projections do not reopen the source.
The original document-wide Markdown, Blocks, and Chunks remain available on the same result.
For dependency-free plain text and an explicit unknown-payload fallback:
OfficeDocumentReader reader = new OfficeDocumentReaderBuilder()
.AddPlainTextHandlers()
.Build();
OfficeDocumentReader.Default intentionally has no format handlers. This keeps Core honest: adding a format is an
explicit package and builder decision, while every built reader remains immutable and instance-scoped.
Incremental ingestion
Use Enumerate when a consumer can process and discard one chunk at a time:
var reader = new OfficeDocumentReaderBuilder().AddPlainTextHandlers().Build();
var options = ReaderOptions.CreateSafeIngestion();
options.ComputeHashes = false;
foreach (ReaderChunk chunk in reader.Enumerate("large.txt", options)) {
IndexChunk(chunk);
}
EnumerateAsync provides asynchronous pull and backpressure on .NET 8 and .NET 10.
Plain text supports paths and forward-only streams. CSV and Excel provide incremental path output through
their existing row-extraction engines. Excel still opens the owning workbook model and metadata; incremental
output avoids building the complete Reader result graph. Other handlers use a materialized fallback.
Check SupportsIncrementalPath and SupportsIncrementalStream in GetCapabilities().
Document processors require a complete result and therefore use the materialized path. Source hashing reads
the entire source before output; forward-only inputs use a materialized fallback to preserve the source hash.
Disable ComputeHashes for earliest first-chunk delivery. Dispose the
enumerator when stopping early. A seekable stream reads from the beginning and restores its original position;
a forward-only stream starts at its current position. The caller keeps stream ownership and must keep its
input stable during enumeration. Content-first routing uses the snapshot-based materialized contract.
Bound a batch by source bytes
Set ReaderBatchOptions.MaxTotalBytes to bound the combined source lengths accepted by a batch.
When set, reads run in input order so each native owner receives the remaining allowance;
MaxDegreeOfParallelism remains an upper bound. Per-file and registered default limits still apply.
Directory packages use their native bounded reader and snapshot length.
ReadDocumentsDetailedAsync and ReadDocumentsAsCompletedAsync report a source that does not fit
as a failed outcome and continue with the remaining sources. ReadDocumentsAsync throws instead.
The other operation budgets still span the complete batch; terminal safety limits retain their
existing behavior.
Reuse an immutable read policy
OfficeDocumentReaderBuilder.WithDefaultOptions(options) captures common read and folder settings.
Registration and Build() each snapshot the policy, including nested budgets, encoding and folder
selection. Changing the original options, the builder or the copy returned by reader.DefaultOptions
does not reconfigure an existing reader.
Omitting per-read options uses that profile across path, stream, bytes, incremental, asynchronous,
folder and batch routes. An explicit ReaderOptions object replaces the complete common profile;
it does not merge individual fields. Explicit ReaderFolderOptions similarly replace folder defaults.
Standalone detection retains its own ReaderDetectionOptions contract, and DetectKind remains an
extension lookup that does not open a file.
Operation budgets and decoding
ReaderOptions.CreateSafeIngestion() sets a 64 MiB input limit and finite aggregate budgets for chunks,
characters, blocks, assets and nested content. Its values are a starting policy that applications can tighten:
var options = ReaderOptions.CreateSafeIngestion();
options.ResourceLimits!.MaxChunks = 2_000;
options.ResourceLimits.MaxNestedInputBytes = 32L * 1024 * 1024;
options.ResourceLimits.MaxNestedDepth = 3;
options.ThrowOnInvalidTextBytes = true;
ResourceLimits is optional; unset budgets remain unlimited. Limits span the root and its nested reads,
all files in one folder operation, and all workers in one batch. Exceeding them throws
ReaderResourceLimitException and ends the operation, including resilient folder and batch routes.
MaxChunkCharacters counts both Text and Markdown. Nested input budgets count decoded entries,
including intermediate archive payloads. Shared chunk/block objects and asset byte arrays count once.
Rich-model limits are checked when the engine returns its model; retain the owning format's parser,
archive, decompression and asset limits to control allocations inside that engine.
MaxChars is a best-effort projection target. Atomic Markdown blocks and tables can exceed it with a warning;
Reader preserves their complete content. Use ResourceLimits.MaxChunkCharacters for a terminal operation limit.
Folder and detailed path reads run the same configured processors as single-document reads.
Plain-text handlers recognize UTF-8, UTF-16 and UTF-32 BOMs. Without a BOM they use UTF-8 or the supplied
TextEncoding. Replacement decoding emits a warning; ThrowOnInvalidTextBytes rejects malformed bytes.
BOMs override TextEncoding. These options apply to plain-text handlers; other formats use their own
codec policies. Chunk boundaries preserve Unicode surrogate pairs, and line breaks normalize to LF.
Text and metadata projection
Supporting handlers can read text and metadata without building secondary Markdown, asset, visual, form or OCR projections:
var options = ReaderOptions.CreateSafeIngestion();
options.Projection = ReaderProjection.TextAndMetadata;
OfficeDocumentReadResult document = reader.ReadDocument("Policy.docx", options);
The default is ReaderProjection.Full. Check each handler's SupportsTextAndMetadata capability
and TextAndMetadataExtensions before requesting the lean projection. An empty extension list means
no extension restriction for a supporting handler; a nonempty list identifies its qualified subset.
Unsupported handlers and formats reject the request before parsing rather than silently running a full read.
Several legacy Office imports reconstruct pictures as part of loading and therefore remain Full-only.
The lean result retains text, source locations, metadata and configured native inspection evidence.
Its CapabilitiesUsed includes officeimo.reader.projection.text-and-metadata; an empty asset collection
in that profile means asset projection was not requested, rather than proving the source contains no images.
Options are snapshotted, and nested reads inherit the lean operation profile. Core does not reconstruct
unrequested Markdown when refreshing a text processor's changes.
This projection avoids secondary work; it is not a hard process-memory limit. Keep native parser, package expansion and input limits alongside aggregate output budgets. Format owners document any source structures that must still be decoded or validated during loading.
Nested results and qualified capabilities
ZIP and email reads keep each delegated source's rich result in NestedDocuments, alongside the existing
flattened chunks. Each item supplies its virtual Path and complete Document, including available links,
forms, metadata, diagnostics and assets. Identifiers inside a child result remain local to that child.
Asset payload bytes stay in memory when requested and remain excluded from JSON transport.
Document transport schema version 14 adds Publisher input identity (ReaderInputKind.Publisher, 30).
Version 13 adds DBF input identity (ReaderInputKind.Dbf, 29).
Version 12 adds DjVu identity (ReaderInputKind.DjVu, 28); version 11 adds CHM identity
(ReaderInputKind.Chm, 27). Version 10 adds XPS/OpenXPS identity and explicit native
ReaderLocation.LogicalOrder across physical containers; version 9 includes recursive
nestedDocuments. Versions 5 through 13 remain readable. Load the matching artifact
with OfficeDocumentReadResultSchema.GetJsonSchema(version). Versions below 9 cannot
carry nested documents, below 10 cannot carry XPS input kinds, below 11 cannot carry
CHM input kinds, below 12 cannot carry DjVu input kinds, below 13 cannot carry DBF input kinds,
and below 14 cannot carry Publisher input kinds.
Capability manifest version 7 includes incremental route flags, per-extension FormatQualifications, and lean-projection support.
A qualification records a format ID, extraction maturity, profile, preservation, limitations and evidence
references. Word, Excel and modern PowerPoint reuse their owner's format IDs. Other undeclared profiles
remain Unqualified; an available handler is not a claim of complete format preservation. Applications can
supply immutable ReaderFormatQualification values when registering a custom handler.
For model-specific token budgets, pass a ReaderDelegateTokenCounter to ReaderHierarchicalChunkingOptions:
var chunking = new ReaderHierarchicalChunkingOptions {
MaxTokens = 800,
TokenCounter = new ReaderDelegateTokenCounter("my-model:vocabulary-version", tokenizer.CountTokens)
};
The optional range callback counts the exact prefix-plus-source range without a temporary substring. The application owns tokenizer dependencies and thread safety. The built-in counter estimates one token per four UTF-16 characters; it does not represent a model vocabulary or guarantee a model token budget.
Package selection
| Need | Package |
|---|---|
| Contracts, routing, processors, schemas | OfficeIMO.Reader.Core |
| Word only | OfficeIMO.Reader.Word |
| Excel only | OfficeIMO.Reader.Excel |
| PowerPoint only | OfficeIMO.Reader.PowerPoint |
| Markdown only | OfficeIMO.Reader.Markdown |
| Email artifacts, stores, and OAB | OfficeIMO.Reader.Email |
| PDF only | OfficeIMO.Reader.Pdf |
| Every local managed handler | OfficeIMO.Reader.All |
Other OfficeIMO.Reader.* packages follow the same rule: Core plus the format's owning engine. OCR processes,
network clients, hosted providers, and native tools remain explicit host choices and are not composed by All.
Stable contracts
File reads retain the same source identity and timestamps through synchronous, asynchronous and batch routes. Container result envelopes describe the outer input; member chunks retain their own provenance through document processors. Folder byte limits charge the physical files accepted for parsing. Native async file handlers are awaited directly. Synchronous file handlers run on a worker through the reader's concurrency gate; their file-specific behavior also applies to async and batch reads.
Table exports accept cancellation while scanning and writing rows. Pass a token to
tables.ExportTables(cancellationToken: token) for CSV, Markdown and JSON together, or use
table.ToCsv(token), table.ToMarkdownTable(token) and table.ToJson(indented: true, cancellationToken: token) separately.
ReaderOptionsand format-neutral input/processing limitsReaderChunkand the schema-versionedOfficeDocumentReadResult- tables, pages, visuals, assets, links, forms, metadata, and diagnostics
- sync/async path, stream, byte-array, folder, and batch ingestion
- deterministic capability manifests with
OfficeIMOversusCustomhandler origins - bounded nested-content delegation between configured handlers
Public namespaces remain OfficeIMO.Reader; the .Core name describes package and assembly ownership.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- System.Text.Json (>= 10.0.7 && < 11.0.0)
-
.NETStandard 2.0
- System.Text.Json (>= 10.0.7 && < 11.0.0)
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (36)
Showing the top 5 NuGet packages that depend on OfficeIMO.Reader.Core:
| Package | Downloads |
|---|---|
|
OfficeIMO.Reader.Pdf
PDF reader and normalized PDF projection bridge for OfficeIMO.Reader. |
|
|
OfficeIMO.Reader.Html
HTML adapter for OfficeIMO.Reader using OfficeIMO.Html. |
|
|
OfficeIMO.Reader.Xml
XML adapter extensions for OfficeIMO.Reader. |
|
|
OfficeIMO.Reader.Csv
CSV/TSV adapter for OfficeIMO.Reader.Core. |
|
|
OfficeIMO.Reader.Json
JSON adapter extensions for OfficeIMO.Reader. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.6.1 | 1,024 | 11/10/2026 |
| 3.6.0 | 1,520 | 11/6/2026 |
| 3.5.3 | 1,416 | 10/31/2026 |
| 3.5.2 | 1,550 | 10/24/2026 |
| 3.5.1 | 1,652 | 10/16/2026 |
| 3.4.5 | 1,758 | 10/10/2026 |
| 3.4.4 | 2,311 | 9/27/2026 |
| 3.4.3 | 1,382 | 9/12/2026 |
| 3.4.2 | 1,147 | 9/9/2026 |
| 3.4.1 | 1,138 | 9/7/2026 |
| 3.4.0 | 1,078 | 9/6/2026 |
| 3.3.0 | 1,146 | 9/2/2026 |
| 3.2.7 | 1,197 | 8/29/2026 |
| 3.2.6 | 2,691 | 8/22/2026 |
| 3.2.5 | 1,183 | 8/21/2026 |
| 3.2.4 | 1,112 | 8/19/2026 |
| 3.2.3 | 1,010 | 8/17/2026 |
| 3.2.2 | 1,223 | 8/13/2026 |
| 3.2.1 | 1,140 | 8/11/2026 |
| 3.2.0 | 1,305 | 8/7/2026 |