@ckeditor/ckeditor5-export-word
Version:
Export to Word feature for CKEditor 5.
361 lines (360 loc) • 11.8 kB
TypeScript
/**
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/**
* @module export-word/exportword
* @publicApi
*/
import { Plugin, type Editor } from 'ckeditor5/src/core.js';
import { Notification } from 'ckeditor5/src/ui.js';
import type { InitializedToken, TokenUrl } from '@ckeditor/ckeditor5-cloud-services';
import ExportWordUI from './exportwordui.js';
/**
* The export to Word feature.
*
* It allows you to generate a Word file directly from the editor content.
*
* For a detailed overview, check the {@glink features/converters/export-word export to Word} feature documentation.
*/
export default class ExportWord extends Plugin {
/**
* @inheritDoc
*/
static get pluginName(): "ExportWord";
/**
* @inheritDoc
*/
static get isOfficialPlugin(): true;
/**
* @inheritDoc
*/
static get isPremiumPlugin(): true;
/**
* @inheritDoc
*/
static get requires(): readonly ["CloudServices", typeof Notification, typeof ExportWordUI];
/**
* @inheritDoc
*/
init(): void;
}
/**
* The configuration of the export to Word feature. It is used by the Word export features from
* the `@ckeditor/ckeditor5-export-word` package.
*
* ```ts
* ClassicEditor
* .create( editorElement, {
* exportWord: ... // Export to Word feature options.
* } )
* .then( ... )
* .catch( ... );
* ```
*
* See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
*/
export interface ExportWordConfig {
/**
* Paths to the `.css` files containing additional styling for the editor's content (**the order of provided items matters**).
*
* ```ts
* const exportWordConfig = {
* stylesheets: [ './path/to/custom-style.css' ]
* }
* ```
*
* **Default editor's content styles**:
* {@glink getting-started/setup/css The default editor content styles}
* are applied to the generated Word file thanks to the `'EDITOR_STYLES'` token, which is provided to the `stylesheets` by default.
* If you don't want them to be applied, you have to omit the token:
*
* **NOTE:** The `'EDITOR_STYLES'` string is only supported in legacy custom builds with webpack or DLLs.
* In other setups you always need to pass the stylesheets.
*
* ```ts
* const exportWordConfig = {
* stylesheets: [ './path/to/custom-editor-styles.css' ]
* }
* ```
*
* **Custom styling:** For more advanced styling, your configuration should look like this:
*
* ```ts
* const exportWordConfig = {
* stylesheets: [
* './path/to/editor-styles.css',
* './path/to/custom-styles.css'
* ]
* }
* ```
*
* @default `[ 'EDITOR_STYLES' ]`
*/
stylesheets?: Array<string>;
/**
* The name of the generated Word file.
*
* ```ts
* // Static file name.
* const exportWordConfig = {
* fileName: 'my-document.docx'
* }
*
*
* // Dynamic file name.
* const exportWordConfig = {
* fileName: () => {
* const articleTitle = document.querySelector( '#title' );
*
* return `${ articleTitle.value }.docx`;
* }
* }
* ```
*
* **NOTE:** The file name must contain the `.docx` extension.
* Otherwise your operating system or device may have trouble identifying the file type.
*
* @default 'document.docx'
*/
fileName?: string | (() => string);
/**
* A URL to the Docx converter.
*
* ```ts
* const exportWordConfig = {
* converterUrl: 'https://myconverter.com/v2/'
* }
* ```
*
* **NOTE:** The plugin uses the default HTML to Word converter delivered by CKEditor Cloud Services.
* You can provide a URL to an on-premises converter instead.
*
* @default 'https://docx-converter.cke-cs.com/v2/convert/html-docx'
*/
converterUrl?: string;
/**
* The CKEditor Cloud Services HTML to DOCX Converter [configuration options](https://docx-converter.cke-cs.com/docs#section/Options).
*
* **NOTE:** Configuring the plugin is not mandatory.
*
* ```ts
* const exportWordConfig = {
* converterOptions: {
* ...
* }
* }
* ```
*
* @default `{
* document: {
* size: 'A4',
* orientation: 'portrait',
* language: editor.locale.contentLanguage,
* margin: {
* top: '1in',
* bottom: '1in',
* right: '1in',
* left: '1in'
* }
* }
* headers: undefined,
* footers: undefined,
* auto_pagination: false,
* base_url: undefined,
* extra_http_headers: undefined
* }`
*/
converterOptions?: ExportWordConverterOptions | ExportWordConverterOptionsV2;
/**
* A function to gather the HTML to be converted to Word.
*
* **NOTE:** This option may be useful when the editor does not have a `getData()` method,
* or if the HTML to be converted should be different than the edited one.
*
* ```ts
* const exportWordConfig = {
* dataCallback: ( editor ) => {
* return `
* <header id="header">${ editor.data.get( { rootName: 'header' } ) }</header>
* <div id="content">${ editor.data.get( { rootName: 'content' } ) }</div>
* `;
* }
* }
* ```
*
* @default `( editor ) => editor.getData( { pagination: true } )
*
* If using the {@glink features/pagination/pagination pagination} feature, the `pagination:true` option inserts additional markers into
* editor's data. Thanks to that, the Docx converter creates a Word document similar to what is displayed in the editor.
*/
dataCallback?: (editor: Editor) => string;
/**
* A token URL or a token request function. This field is optional and should be used only when a different `tokenUrl` is required for
* the export to Word feature.
*
* **Note:** The token can be disabled with the `false` value provided.
*
* See: {@link module:cloud-services/cloudservicesconfig~CloudServicesConfig#tokenUrl}
*/
tokenUrl?: TokenUrl | false;
/**
* The authentication token.
*
* See: {@link module:cloud-services/cloudservices~CloudServices#token}
*/
token?: InitializedToken;
/**
* The version of `Export to Word` API.
*
* @default '2'
*/
version?: 1 | 2;
/**
* The watermark configuration.
*
* ```ts
* converterOptions: {
* watermark: {
* source: 'https://placehold.co/200',
* width: '500px',
* height: '600px',
* washout: 'false'
* }
* }
* ```
*
* The watermark configuration is represented as an object containing 4 properties:
*
* - `source`: A source of the image used for the watermark.
* - `width`: A string value representing the width of the watermark.
* - `height`: A string value representing the height of the watermark.
* - `washout`: Determines whether the washout effect should be applied. Optional - the default value is `false`.
*
*/
watermark?: ExportWordConverterWatermarkV2;
}
export type ExportWordConverterOptions = {
format?: ExportWordConverterFormatOption;
margin_top?: string;
margin_bottom?: string;
margin_right?: string;
margin_left?: string;
header?: ExportWordConverterHeaderFooterOption;
footer?: ExportWordConverterHeaderFooterOption;
comments?: ExportWordConverterCommentsOption;
suggestions?: ExportWordConverterSuggestionsOption;
orientation?: ExportWordConverterOrientationOption;
auto_pagination?: boolean;
base_url?: string;
};
export type ExportWordConverterFormatOption = 'Letter' | 'Legal' | 'Tabloid' | 'Statement' | 'Executive' | 'A3' | 'A4' | 'A5' | 'A6' | 'B4' | 'B5' | string & Record<never, never>;
export type ExportWordConverterOrientationOption = 'portrait' | 'landscape' | string & Record<never, never>;
export type ExportWordConverterHeaderFooterOption = Array<{
html?: string;
css?: string;
type?: 'default' | 'even' | 'odd' | 'first' | string & Record<never, never>;
}>;
export type ExportWordConverterCommentsOption = {
[id: string]: Array<{
author: string;
created: Date;
content?: string;
is_resolved: boolean;
}>;
};
export type ExportWordConverterSuggestionsOption = {
[id: string]: {
author: string;
created: Date | null;
};
};
export type ExportWordConverterOptionsV2 = {
document?: ExportWordConverterDocumentOptionsV2;
headers?: ExportWordConverterHeaderFooterOptionsV2;
footers?: ExportWordConverterHeaderFooterOptionsV2;
extra_http_headers?: ExportWordConverterExtraHttpHeaders;
base_url?: string;
auto_pagination?: boolean;
watermark?: ExportWordConverterWatermarkV2;
};
export type ExportWordConverterDocumentOptionsV2 = {
margins?: ExportWordConverterMarginsOptionsV2;
size?: ExportWordConverterFormatOptionsV2;
orientation?: ExportWordConverterOrientationOptionsV2;
language?: string;
};
export type ExportWordConverterMarginsOptionsV2 = {
top?: string;
right?: string;
bottom?: string;
left?: string;
};
export type ExportWordConverterHeaderFooterOptionsV2 = {
first?: ExportWordConverterHeaderFooterItemOptionsV2;
odd?: ExportWordConverterHeaderFooterItemOptionsV2;
even?: ExportWordConverterHeaderFooterItemOptionsV2;
default?: ExportWordConverterHeaderFooterItemOptionsV2;
};
export type ExportWordConverterWatermarkV2 = {
source?: string;
width?: string;
height?: string;
washout?: boolean;
};
/**
* If fetching some resources (e.g. images) used in a generated Word requires passing an additional
* authorization factor in the form of additional HTTP headers:
*
* ```
* extra_http_headers: {
* 'https://ckeditor.com': {
* authorization: 'Bearer xxx'
* },
* 'https://example.com': {
* authorization: 'Bearer xxx'
* },
* }
* ```
*/
export type ExportWordConverterExtraHttpHeaders = {
[domain: string]: ExportWordConverterExtraHttpHeadersHeader;
};
export type ExportWordConverterExtraHttpHeadersHeader = {
[header: string]: string;
};
export type ExportWordConverterHeaderFooterItemOptionsV2 = {
html?: string;
css?: string;
};
export type ExportWordConverterOrientationOptionsV2 = 'portrait' | 'landscape' | string & Record<never, never>;
export type ExportWordConverterFormatOptionsV2 = ExportWordConverterPredifinedFormatOptionsV2 | ExportWordConverterCustomFormatOptionsV2;
export type ExportWordConverterPredifinedFormatOptionsV2 = 'Letter' | 'Legal' | 'Tabloid' | 'Statement' | 'Executive' | 'A3' | 'A4' | 'A5' | 'A6' | 'B4' | 'B5' | string & Record<never, never>;
export type ExportWordConverterCustomFormatOptionsV2 = {
width?: string;
height?: string;
};
export type ExportWordConverterCollaborationFeaturesOptionsV2 = {
comment_threads?: ExportWordConverterCommentsThreadOptionsV2;
suggestions?: ExportWordConverterSuggestionsOptionsV2;
};
export type ExportWordConverterCommentsThreadOptionsV2 = Array<{
thread_id: string;
is_resolved: boolean;
comments: ExportWordConverterCommentsV2;
}>;
export type ExportWordConverterCommentsV2 = Array<{
author: string;
created_at: Date;
content: string;
}>;
export type ExportWordConverterSuggestionsOptionsV2 = Array<{
id: string;
author: string;
created_at: Date | null;
}>;
export type ExportWordConverterMergeFieldsOptionsV2 = {
prefix: string;
suffix: string;
data?: Record<string, string>;
};