---
title: "Convert ODT to DOCX in C#"
url: https://recursiveai.org/onedocument/cookbook/convert-odt-to-docx/
description: "Convert ODT to DOCX in C# with OneDocument for .NET 10. Runnable code, sample input and a downloadable example with real output."
version: "1.0.0"
---

# Convert ODT to DOCX in C#

**OneDocument** is a free, open-source Word, Excel and PowerPoint document library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneDocument.Documents) · [GitHub](https://github.com/recursive-ai-oss/onedocument-csharp) · [Docs](https://recursiveai.org/onedocument/docs/) · [Download example (.zip)](https://recursiveai.org/onedocument/cookbook/convert-odt-to-docx/convert-odt-to-docx.zip)

ODT is OpenDocument’s text format.

```shell
dotnet add package RecursiveAI.OneDocument.Documents
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneDocument.Documents;
using var doc = Document.Open("input.odt");
doc.SaveAs("output.docx");
```

Writes output.docx; prints nothing. The zip’s input.odt contains “Quarterly report” and “Revenue grew this quarter.”

Unzip [the example](https://recursiveai.org/onedocument/cookbook/convert-odt-to-docx/convert-odt-to-docx.zip), then `dotnet run`.

## The full program

The program creates that two-paragraph ODT, opens it into the shared document model (the “hub”), saves DOCX, and prints import and export loss counts and any loss codes. Finally, it reopens the DOCX and reads the text.

```csharp
using RecursiveAI.OneDocument.Documents;

using (Document seed = Document.Create())
{
    seed.Body.AddParagraph("Quarterly report");
    seed.Body.AddParagraph("Revenue grew this quarter.");
    seed.SaveAs("input.odt");
}
using Document doc = Document.Open("input.odt");
doc.SaveAs("output.docx");
Console.WriteLine("Wrote output.docx");
Console.WriteLine($"Import losses: {doc.ImportLoss?.Items.Count ?? 0}");
Console.WriteLine($"Export losses: {doc.ExportLoss?.Items.Count ?? 0}");
foreach (var loss in doc.ImportLoss?.Items ?? [])
    Console.WriteLine($"Import: {loss.Code}");
foreach (var loss in doc.ExportLoss?.Items ?? [])
    Console.WriteLine($"Export: {loss.Code}");
using Document saved = Document.Open("output.docx");
Console.WriteLine(saved.ExtractText().Trim());
```

`dotnet run` prints:

```text
Wrote output.docx
Import losses: 0
Export losses: 0
Quarterly report
Revenue grew this quarter.
```

Encrypted ODF packages raise `OfficeUnsupportedException`; ODF encryption is not implemented.

## Variations

**Read import loss codes before saving.** This lets your application decide whether to accept a conversion.

```csharp
using RecursiveAI.OneDocument.Documents;
using var doc = Document.Open("input.odt");
Console.WriteLine($"Import losses: {doc.ImportLoss?.Items.Count ?? 0}");
foreach (var loss in doc.ImportLoss?.Items ?? [])
    Console.WriteLine(loss.Code);
doc.SaveAs("reviewed.docx");
```

```text
Import losses: 0
```

## Related recipes

- [Convert DOC to DOCX](https://recursiveai.org/onedocument/cookbook/convert-doc-to-docx/)
- [Convert Markdown to DOCX](https://recursiveai.org/onedocument/cookbook/convert-markdown-to-docx/)
- [Convert DOCX to PDF](https://recursiveai.org/onedocument/cookbook/convert-docx-to-pdf/)

---

## The short answer

To convert ODT to DOCX in C#, use OneDocument’s Documents package: `Document.Open` reads the ODT into the word-processing hub and `SaveAs` writes a `.docx` file. This API reads the OpenDocument structure and maps supported content into an in-memory DOCX package.

The downloadable example uses two plain paragraphs so that the input is visible and easy to inspect. It reports zero import and export losses for that sample, then reopens the saved DOCX and prints its text. That result applies to this small document, not every ODT file.

## Can you convert ODT to docx?

Yes. `Document.Open` accepts ODT, OTT and FODT by content, using the package’s mimetype entry or the flat document’s `office:mimetype`, rather than trusting the extension. The opened object retains its source format in `Document.Format`, even though the internal hub is a DOCX package. Saving to a `.docx` filename chooses DOCX output.

For an application, keep the source and destination paths separate, as this example does. Read `ImportLoss` after opening; inspect `ExportLoss` after saving. A conversion report gives your code a way to distinguish a simple accepted mapping from a document with unsupported content. The [ODF documentation](https://recursiveai.org/onedocument/docs/odf/) lists supported mappings and loss codes.

## How to convert ODT to Word doc?

This recipe writes DOCX, not the older binary DOC format. The output extension in `SaveAs("output.docx")` is part of that choice. It does not require starting a desktop Word application.

Paragraphs, headings, text formatting, tables, lists, headers, footers, comments and tracked changes have documented ODF-to-hub mappings. That does not mean every layout feature survives identically. Shapes can keep text while losing geometry. Embedded objects, including charts, keep only a preview picture. Linked images are never fetched. Mathematical formulas can keep symbols as text rather than an editable equation. These are practical reasons to inspect the report and review a representative document before converting a collection.

An unreadable XML part raises its typed error when first used. A loss report covers mapped content that could not be carried; it is not a substitute for handling file-opening exceptions.

## Are ODT and DOCX the same?

No. In this library they are distinct file formats connected through a shared document model. Opening ODT is an import, not a change of filename. Saving DOCX serializes that model to a different package structure. Zero reported losses does not establish identical page breaks in every viewer, and the text readback in this example checks text, not page layout.

There is also a distinction between converting and preserving an untouched source. The docs state that an ODT, OTT or FODT read and saved in its own format without an edit writes the original bytes. That preservation behavior does not describe an ODT-to-DOCX conversion: a different output format necessarily goes through the hub. Once you edit an ODT and save it back as OpenDocument, the exporter writes its own package and reports what it could not carry. Treat `ImportLoss` and `ExportLoss` as separate stages rather than assuming the final report summarizes the whole journey.
