Table of Contents

Namespace DocToolkit

Classes

DocToolkitTelemetry

The names to subscribe to for DocToolkit's telemetry.

builder.Services.AddOpenTelemetry()
    .WithTracing(t => t.AddSource(DocToolkitTelemetry.ActivitySourceName))
    .WithMetrics(m => m.AddMeter(DocToolkitTelemetry.MeterName));

Only the opt-in remote-image fetch is instrumented, and that is a deliberate scope rather than a first instalment. Every other call in this package is one synchronous, in-process, stateless operation that throws a typed exception on failure — a caller can time and log around it and learn everything a span would tell them. The fetch path is the exception: it is the only place this library reaches the network, the decision to allow or refuse a host happens deep inside HtmlToOpenXml's pipeline, and a refused fetch is deliberately silent — the image is skipped and the document still succeeds. Without this, a consumer who enabled remote images had no way to find out that an image never arrived, or why.

DocumentConversionException

Thrown when a document conversion fails.

DocxBlock

One block of content in a document built by Create(IEnumerable<DocxBlock>).

The hierarchy is CLOSED: the constructor is private protected, the concrete types are internal sealed, and a block can only be obtained from one of the factory methods below. A consumer therefore cannot define a block the writer has never heard of — an unrenderable block is unrepresentable rather than a runtime failure.

Each factory validates its arguments immediately, so a bad value throws at the line that produced it rather than later inside a Create(IEnumerable<DocxBlock>) call assembling many blocks at once.

DocxEditor

Creates, reads and edits Word (.docx) documents.

DocxToHtmlConverter

Converts a Word (.docx) package to HTML, keeping the structure ExtractText(byte[]) throws away: headings stay headings, tables stay tables. Use ExtractText when flat text is what you want.

The result is a complete HTML document<html><head>…<body> — not a fragment, and there is no option to change that. Embedding the output in a larger page means extracting the body with an HTML parser you already trust; this package will not do it by string surgery on the renderer's output.

The result is self-contained. Images in the source document are embedded as data: URIs, so nothing in the output points at a file that does not exist.

DocxToMarkdownConverter

Converts a Word (.docx) package to Markdown, keeping the structure ExtractText(byte[]) throws away: a heading becomes #, a table becomes a pipe table. Use ExtractText when flat text is what you want.

The result is self-contained. Images in the source document are embedded as data: URIs rather than written beside the output and referenced by path, so the string this returns stands on its own.

DocxToPdfConverter

Renders a Word (.docx) package to PDF. Pure managed - no browser, no LibreOffice.

HtmlToDocxConverter

Converts an HTML fragment into a Word (.docx) package.

HtmlToPdfConverter

Converts HTML to PDF by pivoting through DOCX.

There is no permissive, NuGet-only, Linux-safe library that renders HTML to PDF directly: the only free renderers are browsers, and a browser is a native binary. Pivoting through DOCX keeps the whole chain pure managed. See learning-docs/dotnet-doc-libs/report.html.

PageSetup

The paper a generated document is laid out on: size, orientation and margins, all in points.

Immutable and built by factories — A4, Letter or Custom(double, double) — then copied by Landscape() and WithMargins. The same shape as DocxBlock, PptxSlide, XlsxSheet and XlsxFormula, so the five read as a set.

Points throughout, because Image(byte[], double?, double?, string?) already takes widthPoints/heightPoints, and a library with two length units is a library that will eventually mix them up. OOXML stores these as twentieths of a point; that conversion lives in SectionPropertiesFactory and never reaches a caller.

Only two presets. A3, Legal and the rest are one line each and can be added when somebody asks; Custom(double, double) covers them meanwhile.

There is no Portrait(). It has no defensible answer for a square custom page — "the longer side vertical" is undefined when there is no longer side. Both presets are already portrait and this type is immutable, so start from the preset again.

PdfEditor

Operations on a PDF that already exists: how many pages it has, joining several into one, taking a range of pages out, and reading or stamping its document information.

PdfMetadata

The document information a PDF carries about itself — what a file manager shows in its properties panel, and what a search indexer reads.

PptxSlide

One slide: a title and zero or more bullet lines. Built by Titled(string, params string[]) and passed to Create(IEnumerable<PptxSlide>).

A single sealed type rather than the closed hierarchy DocxBlock uses. That hierarchy exists because a document has four kinds of block an external assembly must not be able to extend; a deck has one kind of slide in this version, so the same machinery would be cost without benefit. Titled(string, params string[]) leaves room for other factories later without changing what already exists.

PptxToPdfConverter

Renders a PowerPoint (.pptx) presentation to PDF, one page per slide. Pure managed — no browser, no LibreOffice, no PowerPoint.

The same three members as DocxToPdfConverter and XlsxToPdfConverter, deliberately: a consumer who has used one has used all three.

No page-setup parameter. A presentation's page size is its p:sldSz — slide geometry, not paper. PresentationEditor writes 16:9, which renders as a 960 × 540 pt PDF page. Accepting a PageSetup here would invite a caller to letterbox their own slides onto a paper size that means nothing to a deck.

Fidelity is bounded, and features the renderer cannot represent are dropped rather than reported — see README's Known limitations.

PresentationEditor

Opens and edits PowerPoint (.pptx) presentations.

RemoteImageOptions

Bounds the one code path in this library that opens a socket: fetching images named by absolute URLs during HTML conversion. Every default here is the restrictive one, so new RemoteImageOptions() is safe to pass without reading this class.

This is not a complete SSRF defence. Host addresses are resolved and checked, then resolved again by the HTTP stack when it connects — a DNS entry that changes between those two moments defeats the check. It stops the ordinary cases, a literal metadata address or a hard-coded internal hostname, and raises the cost of the rest; a service converting genuinely untrusted HTML should also be egress-filtered at the network layer.

WorkbookEditor

Creates, reads and edits Excel (.xlsx) workbooks. Legacy .xls is not supported.

XlsxFormula

A cell value meaning "this cell holds a formula". Use it anywhere a cell value is accepted — inside XlsxSheet rows, inside rows passed to AppendRows(byte[], string, IEnumerable<IEnumerable<object?>>), or as the value argument to SetCell(byte[], string, string, object?).

No cached result is written. The file carries the formula and nothing else. Excel recalculates when it opens the file, and this package's own readers (ReadCell(byte[], string, string), ReadSheet(byte[], string)) compute the value on read — but a third-party reader that only reads cached values, such as openpyxl with data_only=True, sees an empty cell until Excel has opened and saved the file.

A formula that cannot be evaluated reads back as its Excel error string — #DIV/0!, #NAME?, #REF! — rather than throwing, which is what Excel itself shows.

XlsxSheet

One named sheet and its rows, for building a multi-sheet workbook from data rather than a template.

Content comes from data rather than a template, so there is no source file to edit. Cell typing and culture rules are identical to the single-sheet Create(string, IEnumerable<IEnumerable<object?>>); a cell holding an XlsxFormula is written as a formula.

There is deliberately no separate header row. A header is styling, and this type carries content — the first row is a header only in the sense that you put your headings in it.

XlsxToPdfConverter

Renders an Excel (.xlsx) workbook to PDF. Pure managed — no browser, no LibreOffice, no Excel.

The same three members as DocxToPdfConverter and PptxToPdfConverter, deliberately: a consumer who has used one has used all three.

No page-setup parameter, for the same reason DocxToPdfConverter has none — the workbook already carries its own print setup, per worksheet, and the renderer honours it. Taking a PageSetup here would mean overriding something the caller's own document already states.

Fidelity is bounded, and features the renderer cannot represent are dropped rather than reported: this package has no warning channel, and adding one is a decision deferred until somebody needs it rather than made by accident here. See README's Known limitations.