Skip to content

Common API Conventions

This document describes the office-sdk entry points, instance lifecycle, common types, event model, and color parameters. Product-specific component methods are documented in DOCX, XLSX, and PPTX.

Entry Points

Public entries live in the deployed static asset directory. The examples below assume lib/ is mapped to /office-sdk/:

html
<link rel="stylesheet" href="/office-sdk/style.css" />

<script type="module">
  import "/office-sdk/preload.js";
  import OfficeSdk from "/office-sdk/UI.js";
</script>

preload is an optional entry that requests key JavaScript runtime files, worker entries, and document app modules ahead of time. It does not preload every .wasm binary or all deployed locale files; the remaining resources load on demand when required during the first document open. Use it when the page will open a document immediately. On ordinary list pages, defer loading until the user initiates opening a document.

Runtime Prerequisites

Opening a document requires:

  • ES Modules and dynamic import()
  • Web Workers, SharedWorkers, and WebAssembly
  • IndexedDB
  • Promise, Blob, and ArrayBuffer

SharedWorker and IndexedDB are required by the current open flow. If either is unavailable, render() fails. Also verify that browser privacy settings, private browsing, enterprise policy, or the host WebView does not disable these capabilities.

The SDK creates its worker directly with new SharedWorker(workerUrl), so deploy the complete lib/ directory on the same origin as the host page. CORS alone does not guarantee that a cross-origin SharedWorker can be created. See the CSP Deployment Guide.

openfile

Signature:

ts
function openfile(
  fileData: OfficeWidgetFileData,
  options?: OfficeSdkOpenOptions | null
): Promise<OfficeWidgetOpenResult>;

Minimal example:

ts
const { docType, widget } = await OfficeSdk.openfile({
  docId: `local-${Date.now()}`,
  fileName: file.name,
  file
});

const app = await widget.mount("#office-container").render();

With user data, UI options, and open mode:

ts
const { widget } = await OfficeSdk.openfile(
  {
    docId: "contract-001",
    fileName: "contract.docx",
    file
  },
  {
    userData: {
      userId: "u1",
      clientId: "web-001",
      nickName: "Alice",
      avatar: "https://example.com/avatar.png",
      opts: { color: "#2F80ED" }
    },
    uiOptions: {
      showTopBar: true,
      showBottomBar: true
    },
    mode: {
      readOnly: false,
      lang: "en-US"
    }
  }
);

const app = await widget.mount(document.getElementById("office-container")!).render();

createfile

Create a new Office file:

ts
type OfficeWidgetCreateDocType = 1 | 2 | 3;

function createfile(
  docType: OfficeWidgetCreateDocType,
  options?: OfficeSdkOpenOptions | null
): Promise<OfficeWidgetOpenResult>;

Parameters:

ParameterTypeRequiredDescription
docTypeOfficeWidgetCreateDocTypeYesIdentifies the type of Office document to create.
optionsOfficeSdkOpenOptions | nullNoCreation options including user information, UI configuration, language, and read-only mode.

Document type identifiers:

IdentifierDocument categoryFile formatExtension
1Word documentOffice Open XML Wordprocessing Document.docx
2Excel workbookOffice Open XML Spreadsheet.xlsx
3PowerPoint presentationOffice Open XML Presentation.pptx
ts
const { widget } = await OfficeSdk.createfile(1, {
  mode: { lang: "en-US" }
});

const app = await widget.mount("#office-container").render();

Each call gets an independent docId. The options, return value, and widget lifecycle are the same as openfile(...).

fileData

ts
type OfficeWidgetFileData = {
  docId?: string;
  fileName: string;
  file: File | Blob | ArrayBuffer | ArrayBufferView | string;
};
FieldRequiredDescription
docIdNoDocument ID used for caching and instance lifecycle identification. If omitted, the SDK generates one from file information.
fileNameYesFile name. The extension identifies the document type. openfile(...) currently supports doc, docx, xls, xlsx, and pptx.
fileYesFile content or a browser-accessible file URL. Supports File/Blob, ArrayBuffer, TypedArray, plus blob:, data:, http(s):, file:, absolute paths beginning with /, and relative paths beginning with ./ or ../. A plain string such as files/a.docx is not recognized as a URL. Do not pass null or undefined.

URL example:

ts
const { widget } = await OfficeSdk.openfile({
  docId: "report-xlsx",
  fileName: "report.xlsx",
  file: "https://example.com/files/report.xlsx"
});

await widget.mount("#office-container").render();

options

ts
type OfficeSdkOpenOptions = {
  userData?: OfficeSdkUser | null;
  uiOptions?: OfficeSdkUiOptions;
  mode?: OfficeSdkOpenMode;
};

type OfficeSdkUser = {
  clientId?: string;
  userId?: string;
  nickName?: string;
  avatar?: string;
  opts?: Record<string, unknown>;
};

type OfficeSdkUiOptions = {
  showTopBar?: boolean;
  showBottomBar?: boolean;
};

type OfficeSdkOpenMode = {
  readOnly?: boolean;
  lang?: "zh-CN" | "en-US" | (string & {});
};
FieldDescription
userDataCurrent user information. If omitted, a default user is filled in: nickName: "Local User", avatar: "", and opts.color: "#2F80ED".
uiOptions.showTopBarWhether to show the top toolbar. If omitted, the SDK default layout is used.
uiOptions.showBottomBarWhether to show the bottom status bar. If omitted, the SDK default layout is used.
mode.readOnlyWhether to open in read-only mode. When true, the SDK sets read-only state after the document loads.
mode.langLanguage, such as zh-CN or en-US. If omitted, the SDK falls back to window.lang, <html lang>, and then browser language.

Return Value

ts
type OfficeWidgetOpenResult = {
  docType: number;
  widget: OfficeWidgetApp;
};

type OfficeWidgetApp = {
  mount(target: string | HTMLElement): OfficeWidgetApp;
  render(): Promise<OfficeRenderedApp>;
  close(): Promise<void>;
  readonly docId: string;
  readonly docType: number;
  readonly docTypeName: string | null;
};

docType values:

ValueType
1Word / DOCX
2Excel / XLSX
3PowerPoint / PPTX

widget.mount(target) supports:

ts
widget.mount("#office-container");
widget.mount("office-container");
widget.mount(document.getElementById("office-container")!);

Strings beginning with #, ., or [ are treated as CSS selectors. Other strings are treated as DOM element IDs. Do not pass selectors that begin with a tag name or a compound prefix, such as "main .office-container".

widget.render() waits until the document is ready and returns the public app API object for the current document. Later APIs are called as app.Component.method(...).

After a successful mount, widget.docTypeName is "WORD", "EXCEL", or "PPT"; before mount completes, it is null.

widget Lifecycle

widget.close() closes the current document instance and releases runtime resources.

MethodSignatureDescription
closeclose(): Promise<void>Closes the current widget and releases the document instance, internal event listeners, and mount resources.

Recommended timing:

  • Before route changes or before the host component unmounts
  • Before the user opens another file
  • When the current document viewer is no longer needed

close() returns Promise<void>. Await it before reusing the same container for a new document.

Close example:

ts
let currentWidget: Awaited<ReturnType<typeof OfficeSdk.openfile>>["widget"] | null = null;

async function openFile(file: File) {
  await currentWidget?.close();

  const { widget } = await OfficeSdk.openfile({
    docId: `local-${Date.now()}`,
    fileName: file.name,
    file
  });

  const app = await widget.mount("#office-container").render();
  currentWidget = widget;
  return app;
}

Error Handling and Troubleshooting

openfile(...) and widget.render() are asynchronous; widget.mount(...) is a synchronous chainable call. Wrap the open and render flow in try...catch and record the original error in logs.

ts
try {
  const { widget } = await OfficeSdk.openfile({
    fileName: file.name,
    file
  });

  await widget.mount("#office-container").render();
} catch (error) {
  console.error("[office-sdk] open failed", error);
}

The external examples include shared/officeWidget.js, which provides classifyError(error) to map common open failures to page-friendly kind, title, and detail values. It is an example helper, not a public API exported by UI.js, and not an SDK API contract. Host applications can follow the same idea, but should not depend on these kind values as SDK return values.

For the example page error-display categories, see shared/README.md in the external distribution package. The API Reference only defines SDK methods, parameters, return values, and instance lifecycle behavior.

app Components

The app returned by render() is the public API object for the current document type. Common components:

Document TypeComponents
DOCXDocument, Paragraph, Table, Selection, Finder, UndoRedo
XLSXDocument, Workbook, Worksheet, Selection, Finder, Cursor, UndoRedo
PPTXDocument, Paragraph, TextBox, Player, Selection, Viewer, UndoRedo

Example:

ts
app.Document.setZoom(120);
app.UndoRedo.undo();

Event Model

Public APIs use component-level event entry points.

Component Events

Components such as Document, Selection, Finder, and UndoRedo inherit common event methods:

ts
type EventStatus =
  | "ok"
  | "no such event"
  | "duplicated event callback"
  | "no such callback";

component.addEventListener(eventName, handler): EventStatus;
component.removeEventListener(eventName, handler): EventStatus;

Usage:

ts
function onSelectionChange(info) {
  console.log(info);
}

const status = app.Selection.addEventListener("SELECTION_CHANGE", onSelectionChange);

if (status !== "ok") {
  console.warn("listen failed:", status);
}

// Pass the same handler function when removing the listener.
const removeStatus = app.Selection.removeEventListener("SELECTION_CHANGE", onSelectionChange);

Use the "Component Events" tables in each product page to determine which component owns an event. Common ownership:

ScenarioComponentExample Events
Document loading, export, zoom, page changesapp.DocumentDOCUMENT_EXPORT_READY, DOCX_END_LOADING, XLSX_WORKSHEET_CHANGE, PPTX_SLIDES_CHANGED
Selection changesapp.SelectionSELECTION_CHANGE
Find panel requestsapp.FinderDOCX_OPEN_FIND_UI, XLSX_OPEN_FIND_UI
Undo/redo state changesapp.UndoRedoUNDO_REDO_STATE_CHANGE

Passing an event name that does not belong to the current component returns "no such event". Component events do not accept an options parameter. If you only need to handle an event once, remove the listener inside the callback:

ts
function onExportReady() {
  app.Document.removeEventListener("DOCUMENT_EXPORT_READY", onExportReady);
  console.log("export ready");
}

app.Document.addEventListener("DOCUMENT_EXPORT_READY", onExportReady);

Color Parameters

DOCX and XLSX commonly use RGB objects:

ts
{ r: 255, g: 0, b: 0 }

RGB objects accept only the r, g, and b channels. The current implementation does not support an a/alpha field.

DOCX also supports theme color objects:

ts
{ name: "accent1", theme: 4, tint: 0, shade: 0 }

XLSX Selection.setFontColor, Selection.setFillColor, and border colors accept RGB, theme color, indexed color, or rgbHex objects directly:

ts
{ r: 255, g: 0, b: 0 }
{ theme: 4, tint: 0 }
{ indexed: 10 }
{ rgbHex: "FFFF0000" }

rgbHex accepts either 6-digit RRGGBB or 8-digit AARRGGBB. Only the 8-digit rgbHex form can carry alpha; it is distinct from the RGB object form, which does not support transparency.

If your business layer uses raw palette UI values such as { hex: "#FF0000", type: "standard", name: "red" }, convert them to the RGB or theme color objects above before passing them to XLSX Selection.* style APIs.

PPTX font colors support strings or objects with hex:

ts
"#4472C4"
"rgb(68, 114, 196)"
{ hex: "#4472C4", type: "theme", name: "accent1" }

The current implementation recommends the { hex: "#RRGGBB" } object form. String parsing has a known limitation when any color channel is 0, so do not rely on string values such as "#FF0000" or "rgb(0, 0, 0)".

Palette APIs return the following shape:

ts
{
  theme: unknown[];
  standard: unknown[];
}

Common Constraints

  • Most style APIs depend on the current selection. They have no effect without a valid selection.
  • Export methods are asynchronous; always await them.
  • exportPdf(...) requires a secure context (normally HTTPS or localhost), window.queryLocalFonts, and permission to access local fonts. If these requirements are not met, the current implementation exits without exporting a PDF.
  • DOCX Table.* requires the current cursor or selection to be inside a table context.
  • XLSX Selection.* targets the current active cell or selection.
  • PPTX Paragraph.* and TextBox.* depend on the currently selected text box or text selection.