🚀 BlockNote AI is here! Access the early preview.
Docs
Export to ODT (Open Document Text)

Exporting blocks to ODT

It's possible to export BlockNote documents to ODT, completely client-side.

This feature is provided by the @blocknote/xl-odt-exporter. xl- packages are fully open source, but released under a copyleft license. A commercial license for usage in closed source, proprietary products comes as part of the Business subscription.

First, install the @blocknote/xl-odt-exporter package:

npm install @blocknote/xl-odt-exporter

Then, create an instance of the ODTExporter class. This exposes the following methods:

import {
  ODTExporter,
  odtDefaultSchemaMappings,
} from "@blocknote/xl-odt-exporter";
 
// Create the exporter
const exporter = new ODTExporter(editor.schema, odtDefaultSchemaMappings);
 
// Convert the blocks to a ODT document (Blob)
const odtDocument = await exporter.toODTDocument(editor.document);

See the full example below:

Customizing the ODT output file

toODTDocument takes an optional options parameter, which allows you to customize different options (like headers and footers).

Example usage:

const odt = await exporter.toODTDocument(testDocument, {
  // XML string
  footer: "<text:p>FOOTER</text:p>",
  // XMLDocument
  header: new DOMParser().parseFromString(
    `<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">HEADER</text:p>`,
    "text/xml",
  ),
});

Custom mappings / custom schemas

The ODTExporter constructor takes a schema, mappings and options parameter. A mapping defines how to convert a BlockNote schema element (a Block, Inline Content, or Style) to the ODT (opens in a new tab) XML element. If you're using a custom schema in your editor, or if you want to overwrite how default BlockNote elements are converted to ODT XML elements, you can pass your own mappings:

For example, use the following code in case your schema has an extraBlock type:

import {
  ODTExporter,
  odtDefaultSchemaMappings,
} from "@blocknote/xl-odt-exporter";
 
new ODTExporter(schema, {
  blockMapping: {
    ...odtDefaultSchemaMappings.blockMapping,
    myCustomBlock: (block, exporter) => {
      return <text:p>My custom block</text:p>;
    },
  },
  inlineContentMapping: odtDefaultSchemaMappings.inlineContentMapping,
  styleMapping: odtDefaultSchemaMappings.styleMapping,
});

Exporter options

The ODTExporter constructor takes an optional options parameter. While conversion happens on the client-side, the default setup uses a server hosted proxy to resolve files:

const defaultOptions = {
  // a function to resolve external resources in order to avoid CORS issues
  // by default, this calls a BlockNote hosted server-side proxy to resolve files
  resolveFileUrl: corsProxyResolveFileUrl,
  // the colors to use in the ODT for things like highlighting, background colors and font colors.
  colors: COLORS_DEFAULT, // defaults from @blocknote/core
};