# DOCX API

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

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

## 组件#

Component | 说明
--- | ---
`Document` | 导出、缩放、分页视图、页码跳转、页面设置、复制剪切粘贴、段落标记、分页符和分节符显示
`Paragraph` | 字体、文字样式、段落对齐、行距、项目符号和编号
`Table` | 表格插入、删除、行列操作、合并与取消合并
`Selection` | 选区、光标、分隔符插入、选区变化事件
`Finder` | 查找、上一个/下一个结果、查找状态
`UndoRedo` | 撤销、重做和可用状态

## 快速示例#

    app.Document.setZoom(120);
    app.Paragraph.setFontName("Arial");
    app.Paragraph.setFontSize(14);
    app.Paragraph.setFontColor({ r: 68, g: 114, b: 196 });

    if (app.Table.isInTable()) {
      app.Table.addRows("End", 1);
    }

    app.Finder.search("合同");
    app.Finder.selectNext();

事件示例：

    function onSelectionChange(info) {
      console.log("selection", info);
    }

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

## Document#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`exportDocument` | `(): Promise<void>` | `Promise<void>` | 导出原始文档。
`exportPdf` | `(printOptions?: unknown): Promise<void>` | `Promise<void>` | 按打印配置导出 PDF。
`setZoom` | `(value: number): void` | `void` | 设置缩放比例，常用值如 `80`、`100`、`120`。
`getZoom` | `(): number` | `number` | 获取当前缩放比例。
`focusEditor` | `(): void` | `void` | 将焦点切回编辑区。
`updateVisibleArea` | `(): void` | `void` | 重新计算可视区域。
`setPageView` | `(mode: "single" \| "multi" \| "wide"): void` | `void` | 切换单页、多页、页宽视图。
`goToPage` | `(pageNum: number): void` | `void` | 跳转到页码，`pageNum` 从 `1` 开始。
`getCurrentPagePosition` | `(pageIndex?: number): PagePosition \| {}` | `PagePosition \| {}` | 获取页码信息；`pageIndex` 为页索引，从 `0` 开始，不传取当前页。当前实现不会稳定区分显式传入的 `0` 与未传值。
`setPageOrientation` | `(value: "Portrait" \| "Landscape"): void` | `void` | 设置页面纵向或横向。
`setPageSize` | `(width: number, height: number): void` | `void` | 设置页面宽高，内置 UI 按厘米值传入。
`copy` | `(): Promise<void>` | `Promise<void>` | 触发编辑区复制。
`cut` | `(): Promise<void>` | `Promise<void>` | 触发编辑区剪切。
`paste` | `(): Promise<void>` | `Promise<void>` | 触发编辑区粘贴。
`startReadOnly` | `(): void` | `void` | 进入只读状态。
`endReadOnly` | `(): void` | `void` | 退出只读状态。
`isReadOnly` | `(): boolean` | `boolean` | 获取当前只读状态。
`setShowParagraphMarks` | `(value: boolean): void` | `void` | 设置是否显示段落换行标记。
`getShowParagraphMarks` | `(): boolean` | `boolean` | 获取段落换行标记显示状态。
`setShowPageBreak` | `(value: boolean): void` | `void` | 设置是否显示分页符标记。
`getShowPageBreak` | `(): boolean` | `boolean` | 获取分页符标记显示状态。
`setShowSectionBreak` | `(value: boolean): void` | `void` | 设置是否显示分节符标记。
`getShowSectionBreak` | `(): boolean` | `boolean` | 获取分节符标记显示状态。

`PagePosition`：

    type PagePosition = {
      pageNum: number;
      pageCnt: number;
      total: number;
    };

Document 示例：

    await app.Document.exportPdf();

    app.Document.setPageView("wide");
    app.Document.goToPage(3);

    const page = app.Document.getCurrentPagePosition();
    console.log(page.pageNum, page.pageCnt, page.total);

    app.Document.setPageOrientation("Portrait");
    app.Document.setPageSize(21, 29.7);
    await app.Document.cut();
    app.Document.setShowParagraphMarks(true);
    app.Document.setShowPageBreak(true);
    app.Document.setShowSectionBreak(true);

Document 支持的组件事件：

事件名 | payload | 说明
--- | --- | ---
`DOCX_PAGE_POSITION_CHANGE` | 无 | 当前页位置变化。
`DOCX_FIRST_PART_LOADING` | `(isLoading: boolean)` | 首批页面加载状态。
`DOCX_END_LOADING` | `(count: number)` | 全部页面加载完成。
`DOCUMENT_EXPORT_READY` | 无 | 导出完成。
`DOCUMENT_EDITING_ENABLED` | 无 | 文档进入可编辑状态。
`DOCUMENT_EDITING_DISABLED` | 无 | 文档退出可编辑状态。
`DOCX_ZOOM_CHANGE` | 无 | 缩放变化。
`DOCX_PART_LOADING` | `(pageIndex: number, ratio: number)` | 分段加载进度，`ratio` 取值范围为 `0` 到 `1`。

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

## Paragraph#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`setBold` | `(value?: boolean): void` | `void` | 设置或切换粗体。不传时按当前选区状态切换。
`setItalic` | `(value?: boolean): void` | `void` | 设置或切换斜体。不传时按当前选区状态切换。
`setUnderline` | `(lineType?: string): void` | `void` | 设置或取消下划线，默认线型为 `"thick"`。
`setStrikeThrough` | `(value?: boolean): void` | `void` | 设置或切换删除线。
`setFontSize` | `(value: string \| number): void` | `void` | 设置字号；空值、非数值会被忽略。
`setFontName` | `(value: string): void` | `void` | 设置字体。
`setFontColor` | `(value: DocxColor): void` | `void` | 设置字体颜色，支持 RGB 或主题色对象。
`getColorPalette` | `(): { theme: unknown[]; standard: unknown[] }` | `{ theme; standard }` | 获取主题色和标准色。
`setAlignment` | `(value: ParagraphAlignment): boolean` | `boolean` | 设置段落水平对齐。
`getAlignment` | `(): ParagraphAlignment \| undefined` | `ParagraphAlignment \| undefined` | 获取当前段落水平对齐。
`setLineSpacing` | `(value: number): void` | `void` | 设置行距倍数，常用值如 `1`、`1.15`、`1.5`、`2`。
`setBulletList` | `(index?: number): boolean \| undefined` | `boolean \| undefined` | 设置或取消项目符号，默认 `index = -1`。
`setNumberedList` | `(index?: number): boolean \| undefined` | `boolean \| undefined` | 设置或取消编号，默认 `index = -1`。

颜色和对齐参数：

    type DocxColor =
      | { r: number; g: number; b: number }
      | { name: string; theme: number; tint?: number; shade?: number };

    type ParagraphAlignment =
      | "Left"
      | "Centered"
      | "Right"
      | "Justified"
      | "Distributed"
      | 0
      | 1
      | 2
      | 3
      | 4;

`ParagraphAlignment` 数字值与 PPTX 对齐枚举一致：`0` 右对齐、`1` 左对齐、`2` 居中、`3` 两端对齐、`4` 分散对齐。

Paragraph 示例：

    app.Paragraph.setBold(true);
    app.Paragraph.setItalic(false);
    app.Paragraph.setUnderline("single");
    app.Paragraph.setStrikeThrough(false);

    app.Paragraph.setFontName("Microsoft YaHei");
    app.Paragraph.setFontSize(16);
    app.Paragraph.setFontColor({ r: 192, g: 0, b: 0 });

    app.Paragraph.setAlignment("Centered");
    app.Paragraph.setLineSpacing(1.5);
    app.Paragraph.setBulletList(0);

## Table#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`insertTable` | `(rows?: number, columns?: number): void` | `void` | 插入表格，默认 `3 x 4`。
`delete` | `(): void` | `void` | 删除当前表格。
`addRows` | `(insertLocation?: InsertLocation \| number, rowCount?: number): void` | `void` | 在当前位置插入行，默认向后插入 1 行；第一个参数传数字时表示行数。
`addColumns` | `(insertLocation?: InsertLocation \| number, columnCount?: number): void` | `void` | 在当前位置插入列，默认向右插入 1 列；第一个参数传数字时表示列数。
`deleteRows` | `(rowCount?: number): void` | `void` | 删除当前行，默认删除 1 行。
`deleteColumns` | `(columnCount?: number): void` | `void` | 删除当前列，默认删除 1 列。
`mergeCells` | `(): void` | `void` | 合并当前选中的单元格。
`unmergeCells` | `(): void` | `void` | 取消合并单元格。
`isInTable` | `(): boolean` | `boolean` | 当前选区是否在表格内。

    type InsertLocation =
      | "Start"
      | "Before"
      | "Left"
      | "start"
      | "before"
      | "left"
      | "End"
      | "After"
      | "Right"
      | "end"
      | "after"
      | "right";

`"Start"`、`"Before"`、`"Left"` 及其小写形式表示向前或向左插入；其他值按默认 `"End"` 处理，即向后或向右插入。

Table 示例：

    app.Table.insertTable(3, 5);

    if (app.Table.isInTable()) {
      app.Table.addColumns("End", 1);
      app.Table.addRows(2);
      app.Table.mergeCells();
    }

## Selection#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`getSelectedText` | `(options?: unknown): string` | `string` | 获取当前选区文本；没有有效选区时返回空字符串。
`getParagraphInfo` | `(pageIndex?: number): ParagraphInfo` | `ParagraphInfo` | 获取段落所在行列和选区 ID。
`clearSelection` | `(): void` | `void` | 清空页面选区高亮。
`hideCursor` | `(): void` | `void` | 隐藏光标。
`insertBreak` | `(type?: BreakType): void` | `void` | 插入分页符、分节符或分栏符。

    type ParagraphInfo = {
      row: number;
      col: number;
      selection: {
        startPosId?: string;
        endPosId?: string;
      };
    };

    type BreakType =
      | "Page"
      | "SectionNext"
      | "SectionContinuous"
      | "SectionEven"
      | "SectionOdd"
      | "Column";

Selection 示例：

    app.Selection.insertBreak("Page");
    app.Selection.insertBreak("SectionNext");

    const info = app.Selection.getParagraphInfo();
    console.log(info.row, info.col);

Selection 支持的组件事件：

事件名 | payload
--- | ---
`SELECTION_CHANGE` | `DocxSelectionChange`

    type DocxSelectionChange = {
      bold: boolean;
      italic: boolean;
      fontName: string;
      fontSize: number | string;
      fontColor: unknown;
      underline: boolean;
      strikeout: boolean;
      paraAlignHorizontal:
        | "left"
        | "center"
        | "right"
        | "justify"
        | "distribute"
        | undefined;
      canCopy: boolean;
    };

## Finder#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`search` | `(text: string, callback?: (...args: unknown[]) => void): void` | `void` | 开始查找关键词；可选回调接收运行时返回的查找参数。
`getSelectText` | `(): string \| undefined` | `string \| undefined` | 获取当前选中文本；仅在选中文本长度大于 `0` 且小于 `256` 时返回。
`selectNext` | `(): void` | `void` | 跳到下一个查找结果。
`selectPrevious` | `(): void` | `void` | 跳到上一个查找结果。
`getSearchStatus` | `(): FinderStatus` | `FinderStatus` | 获取当前查找状态。

    type FinderStatus = {
      keyword: string;
      allFounds: unknown[];
      currentIndex: number;
      totalCount: number;
      loop: boolean;
      currentSelect: unknown;
      countNum?: number;
    };

Finder 支持的组件事件：

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

Finder 示例：

    const selectedWord = app.Finder.getSelectText();
    app.Finder.search(selectedWord || "合同");
    app.Finder.selectNext();

    const status = app.Finder.getSearchStatus();
    console.log(status.currentIndex, status.totalCount);

## UndoRedo#

方法 | 签名 | 返回 | 说明
--- | --- | --- | ---
`undo` | `(): void` | `void` | 撤销。
`redo` | `(): void` | `void` | 重做。
`canUndo` | `(): boolean` | `boolean` | 是否可撤销。
`canRedo` | `(): boolean` | `boolean` | 是否可重做。

UndoRedo 支持的组件事件：

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

示例：

    if (app.UndoRedo.canUndo()) {
      app.UndoRedo.undo();
    }