# XLSX API

XLSX API 通过 `widget.render()` 返回的 `app` 调用：

    const { widget } = await OfficeSdk.openfile({ docId: "demo-xlsx", fileName: "demo.xlsx", file });
    const app = await widget.mount("#office-container").render();

## 组件#

Component | 说明
--- | ---
`Document` | 导出、缩放、编辑态和加载事件
`Workbook` | 工作表、调色板、数字格式和保护状态
`Worksheet` | 行列、冻结窗格、行高列宽
`Selection` | 当前选区内容、字体、边框、填充、对齐和数字格式
`Finder` | 查找、上一个/下一个结果、查找状态
`Cursor` | 当前鼠标/光标所在目标区域。
`UndoRedo` | 撤销、重做和可用状态

## 快速示例#

    app.Document.setZoom(125);
    app.Selection.setBold(true);
    app.Selection.setFillColor({ r: 255, g: 242, b: 204 });
    await app.Worksheet.insertRows();

    app.Finder.search("收入");
    app.Finder.selectNext();

事件示例：

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

    app.Selection.addEventListener("SELECTION_CHANGE", onSelectionChange);

## Document#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`isEditing` | `(): boolean` | `boolean` | 当前是否处于单元格内编辑态。
`setZoom` | `(value: number, redraw?: boolean): boolean` | `boolean` | 设置缩放比例；`redraw` 默认 `true`，返回底层缩放操作结果。
`getZoom` | `(): number` | `number` | 获取缩放比例。
`focusEditor` | `(): void` | `void` | 当前 XLSX 实现为空操作。
`updateVisibleArea` | `(): void` | `void` | 重新绘制当前活动工作表可视区域。
`exportDocument` | `(): Promise<void>` | `Promise<void>` | 导出原始工作簿。
`exportPdf` | `(printOptions?: unknown): Promise<void>` | `Promise<void>` | 按打印配置导出 PDF。
`copy` | `(): Promise<void>` | `Promise<void>` | 复制当前选区。
`cut` | `(): Promise<void>` | `Promise<void>` | 剪切当前选区。
`paste` | `(): Promise<void>` | `Promise<void>` | 粘贴到当前选区。
`startReadOnly` | `(): void` | `void` | 进入只读状态。
`endReadOnly` | `(): void` | `void` | 退出只读状态。
`isReadOnly` | `(): boolean` | `boolean` | 获取当前只读状态。

示例：

    if (!app.Document.isEditing()) {
      app.Document.setZoom(110);
    }

    await app.Document.exportDocument();
    await app.Document.exportPdf();

Document 支持的组件事件：

事件名 | payload | 说明
--- | --- | ---
`XLSX_WORKSHEET_LOADED` | 无 | 工作表加载完成。
`XLSX_END_LOADING` | 无 | 文档加载结束。
`DOCUMENT_EXPORT_READY` | 无 | 导出完成。
`DOCUMENT_EDITING_ENABLED` | 无 | 文档进入可编辑状态。
`DOCUMENT_EDITING_DISABLED` | 无 | 文档退出可编辑状态。
`XLSX_EDITING_STATUS_CHANGE` | `(status: boolean)` | 单元格编辑态变化。
`XLSX_ZOOM_CHANGE` | 无 | 缩放变化。
`XLSX_WORKSHEET_LOADING_RATIO` | `(ratio: number)` | 工作表加载进度。
`XLSX_FIRST_PART_LOADING` | 无 | 首批内容加载完成。
`XLSX_WORKSHEET_CHANGE` | `({ sheetProtected?: boolean })` | 当前工作表变化。

`exportPdf(...)` 需要安全上下文（例如 HTTPS 或 localhost）、`window.queryLocalFonts` 和本地字体访问权限。不满足条件时当前实现不会执行 PDF 导出。

## Workbook#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`addWorksheet` | `(): void` | `void` | 新增工作表。
`setWorksheetName` | `(name: string, index?: number): boolean \| number` | `boolean \| number` | 设置工作表名称；`index` 不传时使用活动工作表。返回成功状态或名称校验状态码。
`deleteWorksheet` | `(index?: number): void` | `void` | 删除工作表；`index` 不传时删除活动工作表。
`getWorksheetName` | `(index?: number): string` | `string` | 获取工作表名称；`index` 不传时读取活动工作表。
`getColorPalette` | `(): { theme: unknown[]; standard: unknown[] }` | `{ theme; standard }` | 获取调色板。
`getCellNumberFormats` | `(): string[]` | `string[]` | 获取数字格式分类列表。
`getNumberFormatExample` | `(format: string, value?: unknown, lcid?: unknown): unknown` | `unknown` | 获取一个数字格式示例。
`getNumberFormatExamples` | `(formats: string[], value?: unknown, lcid?: unknown): unknown` | `unknown` | 批量获取数字格式示例。
`isWorksheetProtected` | `(index?: number): boolean` | `boolean` | 判断工作表是否受保护；`index` 不传时检查活动工作表。

示例：

    app.Workbook.addWorksheet();
    app.Workbook.setWorksheetName("汇总");

    const name = app.Workbook.getWorksheetName();
    const protectedSheet = app.Workbook.isWorksheetProtected();

    const formats = app.Workbook.getCellNumberFormats();
    const examples = app.Workbook.getNumberFormatExamples(["0.00", "0%"], 1234.56, "zh-CN");

## Worksheet#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`isFrozenPane` | `(): boolean` | `boolean` | 当前是否冻结窗格。
`toggleFreezePanes` | `(): void` | `void` | 切换冻结/取消冻结窗格。
`setRowHeight` | `(heightPt: number): Promise<unknown>` | `Promise<unknown>` | 设置当前行高；空值会被忽略。
`insertRows` | `(): Promise<unknown>` | `Promise<unknown>` | 插入行。
`hideRows` | `(): Promise<unknown>` | `Promise<unknown>` | 隐藏行。
`unhideRows` | `(): Promise<unknown>` | `Promise<unknown>` | 取消隐藏行。
`deleteRows` | `(): Promise<unknown>` | `Promise<unknown>` | 删除行。
`insertColumns` | `(): Promise<unknown>` | `Promise<unknown>` | 插入列。
`setColumnWidth` | `(nChars: number): void` | `void` | 设置当前列宽，单位为字符宽度；空值会被忽略。
`hideColumns` | `(): Promise<unknown>` | `Promise<unknown>` | 隐藏列。
`unhideColumns` | `(): Promise<unknown>` | `Promise<unknown>` | 取消隐藏列。
`deleteColumns` | `(): Promise<unknown>` | `Promise<unknown>` | 删除列。
`getRowHeight` | `(row?: number \| null, wsIdx?: number \| null): number` | `number` | 获取行高；不传或传 `null` 时读取当前上下文。
`getColumnWidth` | `(col?: number \| null, wsIdx?: number \| null): number` | `number` | 获取列宽；不传或传 `null` 时读取当前上下文。

示例：

    if (!app.Worksheet.isFrozenPane()) {
      app.Worksheet.toggleFreezePanes();
    }

    await app.Worksheet.setRowHeight(24);
    app.Worksheet.setColumnWidth(12);

    const rowHeight = app.Worksheet.getRowHeight();
    const colWidth = app.Worksheet.getColumnWidth();

## Selection#

Selection 方法作用于当前活动单元格或选区。

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`clearContents` | `(): void` | `void` | 清空当前选区内容。
`setAccountingFormat` | `(value: AccountingFormat): Promise<unknown> \| false` | `Promise<unknown> \| false` | 设置会计格式；格式值无效时返回 `false`。
`setUnderline` | `(value: string): void` | `void` | 设置下划线。
`setBorder` | `(value: BorderValue): void` | `void` | 设置边框。
`setStrikeThrough` | `(value: boolean): void` | `void` | 设置删除线。
`setBold` | `(value: boolean): void` | `void` | 设置粗体。
`setItalic` | `(value: boolean): void` | `void` | 设置斜体。
`setFontSize` | `(value: string \| number): void` | `void` | 设置字号；必须为 `0 < value <= 409`。
`setHorizontalAlignment` | `(value: string): void` | `void` | 设置水平对齐。
`setVerticalAlignment` | `(value: string \| number): void` | `void` | 设置垂直对齐；推荐使用字符串值。
`setFontColor` | `(value: XlsxColor): void` | `void` | 设置字体颜色。
`setFillColor` | `(value: XlsxColor): void` | `void` | 设置填充色。
`setFontName` | `(value: string): void` | `void` | 设置字体。
`setCellStyle` | `(value: string): Promise<unknown>` | `Promise<unknown>` | 设置单元格样式。
`setPercentFormat` | `(): Promise<unknown>` | `Promise<unknown>` | 设置百分比格式。
`setNumberFormat` | `(value: unknown): Promise<unknown>` | `Promise<unknown>` | 设置数字格式。
`increaseDecimalPlaces` | `(): void` | `void` | 增加小数位。
`decreaseDecimalPlaces` | `(): void` | `void` | 减少小数位。

    type AccountingFormat = "RMB" | "Dollar" | "EUR" | "GBP" | "JPY" | "none";

    type XlsxColor =
      | { r: number; g: number; b: number }
      | { theme: number; tint?: number }
      | { indexed: number }
      | { rgbHex: string };

    type BorderValue = {
      color: XlsxColor;
      position: string;
      style: string;
    };

`rgbHex` 支持 6 位 `RRGGBB` 或 8 位 `AARRGGBB`。8 位形式可以携带 alpha；`{ r, g, b }` RGB 对象本身不支持透明度。

在单元格文本编辑态下，`setBold`、`setItalic`、`setUnderline` 和 `setStrikeThrough` 会切换当前状态，并忽略传入的布尔值；`setHorizontalAlignment` 和 `setVerticalAlignment` 在该状态下当前不会生效。

常用枚举：

参数 | 常用值
--- | ---
`setUnderline(value)` | `"single"`、`"none"`
`setHorizontalAlignment(value)` | `"left"`、`"center"`、`"right"`、`"justify"`、`"distributed"`
`setVerticalAlignment(value)` | `"top"`、`"center"`、`"bottom"`、`"justify"`、`"distributed"`；兼容运行时数字值
`setAccountingFormat(value)` | `"RMB"`、`"Dollar"`、`"EUR"`、`"GBP"`、`"JPY"`、`"none"`
`BorderValue.position` | `"all"`、`"none"`、`"inner"`、`"outer"`、`"left"`、`"right"`、`"top"`、`"bottom"`、`"verticalInner"`、`"horizontalInner"`、`"diagonalUp"`、`"diagonalDown"`
`BorderValue.style` | `"hair"`、`"dotted"`、`"dashed"`、`"thin"`、`"medium"`、`"thick"`、`"double"`、`"dashDot"`、`"dashDotDot"`、`"mediumDashed"`、`"mediumDashDot"`、`"mediumDashDotDot"`、`"slantDashDot"`；清除边框时使用 `position: "none"`

示例：

    app.Selection.clearContents();

    app.Selection.setFontName("Arial");
    app.Selection.setFontSize(12);
    app.Selection.setBold(true);
    await app.Selection.setAccountingFormat("RMB");
    app.Selection.setFontColor({ r: 192, g: 0, b: 0 });
    app.Selection.setFillColor({ r: 255, g: 242, b: 204 });

    app.Selection.setBorder({
      color: { r: 0, g: 0, b: 0 },
      position: "all",
      style: "thin"
    });

    await app.Selection.setNumberFormat("0.00");
    app.Selection.increaseDecimalPlaces();

Selection 支持的组件事件：

事件名 | payload
--- | ---
`SELECTION_CHANGE` | `XlsxSelectionChange` 或事件原始对象

    type XlsxSelectionChange = {
      bold: boolean;
      italic: boolean;
      fontName: string;
      fontSize: number | string;
      fontColor: unknown;
      underline: string;
      strikeout: boolean;
      fillColor: unknown;
      alignHorizontal: string;
      alignVertical: string;
      numFormat: string;
      numFormatType: string;
      canCopy?: boolean;
      bSelectAll?: boolean;
      isText?: boolean;
    };

## Finder#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`search` | `(text: string, callback?: (...args: unknown[]) => void): void` | `void` | 开始查找关键词，可传回调。
`selectFirst` | `(): void` | `void` | 跳到第一个查找结果。
`selectNext` | `(): void` | `void` | 跳到下一个查找结果。
`selectPrevious` | `(): void` | `void` | 跳到上一个查找结果。
`getSearchStatus` | `(): unknown` | `unknown` | 获取查找状态。

Finder 支持的组件事件：

事件名 | payload | 说明
--- | --- | ---
`XLSX_OPEN_FIND_UI` | 无 | 文档请求打开查找 UI。

示例：

    app.Finder.search("Q1");
    app.Finder.selectFirst();
    app.Finder.selectNext();

    console.log(app.Finder.getSearchStatus());

## Cursor#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`getTargetType` | `(): "" \| "columnHeader" \| "rowHeader" \| "cells" \| "navBar"` | `string` | 获取当前鼠标/光标所在区域。

返回值：

值 | 说明
--- | ---
`""` | 当前没有稳定目标。
`"cells"` | 单元格区域。
`"rowHeader"` | 行头。
`"columnHeader"` | 列头。
`"navBar"` | 底部工作表标签区域。

示例：

    const targetType = app.Cursor.getTargetType();
    if (targetType === "cells") {
      app.Selection.setBold(true);
    }

## UndoRedo#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`undo` | `(callback?: (value: unknown) => void): void` | `void` | 撤销，可传回调。
`redo` | `(callback?: (value: unknown) => void): void` | `void` | 重做，可传回调。
`canUndo` | `(): boolean` | `boolean` | 是否可撤销。
`canRedo` | `(): boolean` | `boolean` | 是否可重做。

UndoRedo 支持的组件事件：

事件名 | payload
--- | ---
`UNDO_REDO_STATE_CHANGE` | 无

示例：

    if (app.UndoRedo.canRedo()) {
      app.UndoRedo.redo();
    }