DocxportNet 1.1.4
See the version list below for details.
dotnet add package DocxportNet --version 1.1.4
NuGet\Install-Package DocxportNet -Version 1.1.4
<PackageReference Include="DocxportNet" Version="1.1.4" />
<PackageVersion Include="DocxportNet" Version="1.1.4" />
<PackageReference Include="DocxportNet" />
paket add DocxportNet --version 1.1.4
#r "nuget: DocxportNet, 1.1.4"
#:package DocxportNet@1.1.4
#addin nuget:?package=DocxportNet&version=1.1.4
#tool nuget:?package=DocxportNet&version=1.1.4
Docxport.Net
Docxport.Net is a .NET library for walking DOCX documents and exporting them to friendly formats. Today it focuses on Markdown (rich and plain), with full handling of:
- Tracked changes (accept/reject/inline views)
- Lists with proper markers and indentation
- Tables
- Comments and threaded replies
- Headers and footers
- Images/drawings
- Bookmarks, hyperlinks, fields, and more
Why this exists
Most DOCX “save as text” pipelines lose important fidelity: strikethroughs and deletions disappear, list markers collapse to bullets or vanish (pandoc), comments/track changes are missing, images are dropped, and tools like LibreOffice/Interop require UI or platform-specific installs. Docxport.Net walks the OOXML directly, headlessly, and emits Markdown/HTML/plain text while preserving tracked changes, comments, list markers, images, headers/footers, and other semantics.
Quick start: DOCX → Markdown
Command line
# From release artifacts (self-contained binary):
./docxport my-doc.docx --format=markdown --tracked=accept
# From source:
git clone https://github.com/gaspardpetit/Docxport.Net.git
dotnet run --project DocxportNet.Cli -- my-doc.docx --format=markdown --tracked=accept
NuGet + code
Install: dotnet add package DocxportNet
using DocxportNet;
using DocxportNet.Visitors.Markdown;
string docxPath = "my-doc.docx";
var visitor = new DxpMarkdownVisitor(DxpMarkdownVisitorConfig.RICH);
string markdown = DxpExport.ExportToString(docxPath, visitor);
File.WriteAllText(Path.ChangeExtension(docxPath, ".md"), markdown);
Tracked changes
Visitors can emit different views of tracked changes:
- Accept changes (default):
DxpTrackedChangeMode.AcceptChanges - Reject changes:
DxpTrackedChangeMode.RejectChanges - Inline markup (insert/delete):
DxpTrackedChangeMode.InlineChanges - Split accept/reject panes:
DxpTrackedChangeMode.SplitChanges
Pick the mode on the visitor config, e.g.:
var config = DxpMarkdownVisitorConfig.RICH with { TrackedChangeMode = DxpTrackedChangeMode.RejectChanges };
var rejectVisitor = new DxpMarkdownVisitor(config);
string rejected = DxpExport.ExportToString(docxPath, rejectVisitor);
Visitors and options
Markdown
- Presets:
DxpMarkdownVisitorConfig.RICH(styled) andPLAIN(minimal). - Options cover images, inline styling, rich tables, comments formatting, custom properties, and tracked change mode.
HTML
- Preset:
DxpHtmlVisitorConfig.RICH. - Options cover inline styles, colors/backgrounds, table borders, document colors, headers/footers, comments mode, custom properties, timeline, and tracked change mode.
Plain text
- Presets:
DxpPlainTextVisitorConfig.ACCEPTandREJECT(choose tracked change handling). - Focused on readable text output with list markers, comments, and basic structure.
DxpExport has overloads for DOCX file paths, in-memory bytes, or an already-open WordprocessingDocument, and can return a string, a byte[], write straight to a file path, or just drive a visitor that collects data.
CLI
A ready-to-use console app lives in DocxportNet.Cli (not published on NuGet). Example:
dotnet run --project DocxportNet.Cli -- my.docx --format=markdown --tracked=accept
# or, when using release artifacts:
./docxport my.docx --format=html --tracked=inline
Options: --format=markdown|html|text, --tracked=accept|reject|inline|split (text uses accept/reject), --plain (plain markdown), --output=path.
Custom visitors
You can write your own DxpIVisitor to extract specific content. Example: collect all comments.
using DocxportNet.API;
using DocxportNet.Visitors;
using DocumentFormat.OpenXml.Wordprocessing;
public sealed class CommentCollector : DxpVisitor
{
public List<(string Author, string Text)> Comments { get; } = new();
public override void VisitComment(Comment c, DxpIDocumentContext d)
{
Comments.Add((c.Author?.Value ?? "Unknown", c.InnerText));
}
}
var collector = new CommentCollector();
DxpExport.Export("my-doc.docx", collector);
foreach (var (author, text) in collector.Comments)
Console.WriteLine($"{author}: {text}");
It also ships a small utility that translates legacy “symbol fonts” (Symbol, Zapf Dingbats, Webdings, Wingdings) into modern Unicode.
Gaps and contributions welcome
| Area | Current gap |
|---|---|
| List markers | Word supports exotic textual markers (“forty-two” in various languages); current formatter covers numeric/roman/alpha/symbol bullets but not full textual spell-outs. |
| Shapes/SmartArt | Complex shapes/SmartArt/OLE rely on preview images if present; true vector or OLE rendering is not implemented. |
| Charts | Charts are emitted via available previews or placeholders; data-driven re-rendering is not implemented. |
| Math/Fields | Core visits are present, but fidelity for complex math/field result rendering isn’t deeply covered by fixtures. |
| Tables (complex) | Merged/nested table edge cases beyond supplied samples may need additional handling. |
Contributions that improve any of these areas are very welcome.
Supported symbol fonts
Symbols typically used in list markers are automatically converted to their unicode equivalent. Supported fonts include:
- Symbol
- Zapf Dingbats
- Webdings
- Wingdings
- Wingdings 2
- Wingdings 3
Symbol font to Unicode
Use DxpFontSymbols when you encounter text that was encoded with a symbol font and you want plain Unicode output.
// Convert a whole string using the font hint.
// 0x41 ('A') -> ✌, 0x42 ('B') -> 👌 in the Wingdings table.
string text = DxpFontSymbols.Substitute("Wingdings", "\u0041\u0042"); // => "✌👌"
// Convert a single character; falls back to the original if unmapped
string bullet = DxpFontSymbols.Substitute("Symbol", (char)0xB7); // → "•"
Unknown characters are returned unchanged. You can optionally supply a replacement character for non-printable glyphs:
// Replace non-printable/control entries with '?'
string safe = DxpFontSymbols.Substitute("Symbol", "\u0001\u00B7", '?'); // => "?•"
Reusing a converter
If you need to translate many strings from the same font or probe whether a font is supported, reuse a converter instance:
var converter = DxpFontSymbols.GetSymbolConverter("Webdings");
if (converter != null)
{
string cat = converter.Substitute((char)0xF6, '?'); // 🐈
string arrows = converter.Substitute((char)0x3C); // ↔
}
Common mappings
- Symbol bullet:
DxpFontSymbols.Substitute("Symbol", (char)0xB7)→• - Webdings cat:
DxpFontSymbols.Substitute("Webdings", (char)0xF6)→🐈 - Wingdings peace/ok:
DxpFontSymbols.Substitute("Wingdings", "\u0041\u0042")→✌👌 - Wingdings 2 left point:
DxpFontSymbols.Substitute("Wingdings 2", (char)0x42)→👈 - Wingdings 3 arrows:
DxpFontSymbols.Substitute("Wingdings 3", "\u0030\u0031")→⭽⭤
| 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 was computed. 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 was computed. 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. |
-
.NETStandard 2.0
- DocumentFormat.OpenXml (>= 3.3.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
-
net8.0
- DocumentFormat.OpenXml (>= 3.3.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.2 | 210 | 3/3/2026 |
| 1.2.1 | 93 | 2/11/2026 |
| 1.2.0 | 132 | 2/7/2026 |
| 1.1.14 | 1,261 | 1/9/2026 |
| 1.1.13 | 105 | 1/9/2026 |
| 1.1.12 | 104 | 1/9/2026 |
| 1.1.11 | 104 | 1/9/2026 |
| 1.1.10 | 97 | 1/9/2026 |
| 1.1.9 | 101 | 1/9/2026 |
| 1.1.8 | 103 | 1/9/2026 |
| 1.1.7 | 110 | 1/8/2026 |
| 1.1.6 | 155 | 1/7/2026 |
| 1.1.5 | 99 | 1/7/2026 |
| 1.1.4 | 747 | 12/22/2025 |
| 1.1.3 | 181 | 12/22/2025 |
| 1.1.2 | 179 | 12/22/2025 |
| 1.1.1 | 176 | 12/22/2025 |
| 1.1.0 | 163 | 12/21/2025 |
| 1.0.1 | 287 | 12/19/2025 |
| 1.0.0 | 254 | 12/19/2025 |