# 开发 Word 文档操作

把样式、编号、表格和页码接到自己的产品按钮，理解节与页面的区别。

本章从已挂载的 Word Classic 开始。`instance.editor` 提供正文命令，`instance.ui` 控制工作区。不要根据按钮文案构造字符串命令；用已安装扩展提供的类型化方法。

## 先分清操作对象

| 用户目标 | 规范对象 | 避免的做法 |
| --- | --- | --- |
| 设置二级标题 | 段落样式身份及定义 | 只放大字体，或套用通用 heading 节点 |
| 连续编号 | 编号定义、实例与段落关联 | 把 `1.` 写进文字 |
| 插入表格 | 逻辑表格、行与网格 | 按屏幕上的分页片段修改 |
| 修改页边距 | 当前文档节 | 用 CSS 改纸张内边距 |
| 显示页码 | 页眉页脚 story 与 PAGE 字段 | 把当前页数作为固定文字保存 |

画面中的一页是排版结果，一个节可以跨多页。Word 表格也可能跨页；命令修改逻辑对象，布局负责重新分页。

## 1. 给当前段落应用样式

使用 `applyWordParagraphStyle({ styleId: 'Heading2' })`，前提是当前文档的样式注册表含有这个 ID。名称来自数据，不能只凭界面显示的中文名称猜 ID。导入的文档可能使用自己的样式身份；缺失时应提示或先通过样式管理流程建立定义。

Word 模型的标题通常仍是带 `wordParagraph.styleId` 的 paragraph，不等于 Core StarterKit 的 heading 节点。字符样式与段落样式也不同；只给选中文字强调时，用字符样式或对应的文字格式命令。

## 2. 编号与表格跟随当前选区

`toggleWordOrderedList()` 在当前段落上建立或移除编号关系；继续编号、重新开始和多级编号还需遵守文档已有定义，不能通过替换显示文本实现。

`insertWordTable({ rowCount: 3, columnCount: 2 })` 插入三行两列的逻辑表格。表格内操作可使用当前结构选区或命令公开的位置参数；每次操作重新读取选区，避免保存滚动前的像素位置作为文档位置。

## 3. 把操作接到按钮

下面四个函数各执行一个任务，沿用[快速接入](/classic/quick-start)创建的 `instance`。它们检查当前 Core 与只读输入状态，仍需应用在调用前检查业务权限。

### classic/word/tasks.ts

```ts
import type { ClassicEditorInstance } from "@quirekit/classic-editor";
// Installing the Word preset supplies these command implementations and declarations.
import type {} from "@quirekit/classic-docx";

/** @param instance - Mounted Word product. @returns Whether the existing Heading2 style was applied. */
export function applySectionHeading(instance: ClassicEditorInstance): boolean {
  const editor = instance.editor;
  return !!editor?.isEditable && editor.commands.applyWordParagraphStyle({ styleId: "Heading2" });
}

/** @param instance - Mounted Word product. @returns Whether a logical two-column table was inserted. */
export function insertComparisonTable(instance: ClassicEditorInstance): boolean {
  const editor = instance.editor;
  return !!editor?.isEditable && editor.commands.insertWordTable({ rowCount: 3, columnCount: 2 });
}

/** @param instance - Mounted Word product. @returns Whether semantic footer page numbering was installed. */
export function addFooterPageNumber(instance: ClassicEditorInstance): boolean {
  const editor = instance.editor;
  return !!editor?.isEditable && editor.commands.setWordPageNumber({
    location: "footer", alignment: "center", format: "decimal", start: 1, template: { kind: "plain" },
  });
}

/**
 * Changes one explicit section rather than a painted page fragment.
 * @param instance - Mounted Word product.
 * @param sectionPosition - Current document position immediately before a wordSection.
 * @returns Whether one-inch horizontal margins were accepted.
 */
export function setOneInchMargins(instance: ClassicEditorInstance, sectionPosition: number): boolean {
  const editor = instance.editor;
  return !!editor?.isEditable && editor.commands.setWordSectionMargins({ sectionPosition, leftTwips: 1440, rightTwips: 1440 });
}

```

把 `applySectionHeading(instance)` 或 `insertComparisonTable(instance)` 放到按钮点击处理函数中。返回 false 时不要显示“操作成功”；可用性查询使用相同参数的 `editor.can()`，它不授予写权限。连续调用多个命令时，也不能把后一步 false 当作前面步骤已回滚。

`setOneInchMargins()` 的位置是 **当前正文中节前的文档位置**，不是页码或屏幕坐标；不要把初始文档的 0 永远用于所有节。此 API 使用 twips，1440 twips 为一英寸。页码示例明确指定位置、格式、起始值与模板，字段值由排版更新。

## 4. 专业能力单独装配

审阅修订、批注流程、内容控件与公文模板等能力按所用专业包安装。标准 Word preset、设置授权码与隐藏按钮都不能代替插件装配；查询[付费使用](/classic/commercial)和[产品插件](/classic/plugins)，逐项接入方法由[插件文档](/plugins)说明。

修订模式下，不是每一种页面或文档级操作都能记录为修订。产品应展示真实能力与诊断；不能把任意命令标成“可接受/拒绝的修改”。

## 5. 用数据与文件验证

应用样式、插入表格、设置页码后，检查 JSON 中的规范身份与关系，再导出并重新导入 DOCX。比较样式、编号、表格网格、节和页眉页脚，查看转换报告；正文文字相同不足以证明 Word 语义保留。跨应用的像素一致性取决于字体与布局支持，不从一次导出成功推断。
