PagesTableKit:用于 Pages 扩展的表格
实验性功能
PagesTableKit 是专为 Pages 扩展构建的。API 和渲染行为可能会在没有通知的情况下变更。如果你依赖它,请锁定确切的包版本。在采用之前,请先阅读 无法使用的内容 部分。
Which setup is right for me?
Two scenarios, one editor stack
PagesTableKit is useful in both scenarios, and the difference is how table content gets into the editor, not how you configure the editor. The base extensions are the same; the second scenario adds the Import extension on top.
- Pages only workflow. You are building a paginated editor (print-friendly layouts, letter-style documents, reports), and you need tables to paginate correctly. The content is handwritten.
- Pages + DOCX import workflow. You are importing
.docxfiles and rendering them in a paginated editor. You need tables to paginate, and to faithfully reflect the original DOCX formatting (declared width, row height, indentation).
Both scenarios use the same editor stack: ConvertKit (for schema) + TableKit (for pagination-safe tables) + Pages (for layout). Scenario B additionally adds ImportDocx. Each section below will indicate which scenario it applies to.
安装
npm i @tiptap-pro/extension-convert-kit \
@tiptap-pro/extension-pages-tablekit \
@tiptap-pro/extension-pages对于场景 B,还需要安装:
npm i @tiptap-pro/extension-import-docx如何配置
PagesTableKit 提供了一个单独的 TableKit 扩展,它将 Table、TableRow、TableCell 和 TableHeader 扩展打包在一起。请只注册一次,而不是分别手动接入这四个扩展。
场景 A:仅 Pages(不导入 DOCX)
注册 ConvertKit(并禁用其内置的表格栈)、PagesTableKit 中的 TableKit,以及 Pages。
import { Editor } from '@tiptap/core'
import { ConvertKit } from '@tiptap-pro/extension-convert-kit'
import { TableKit } from '@tiptap-pro/extension-pages-tablekit'
import { Pages } from '@tiptap-pro/extension-pages'
const editor = new Editor({
extensions: [
ConvertKit.configure({ table: false }), // 禁用 ConvertKit 的表格
TableKit,
Pages.configure({
/* 页面格式、边距等 */
}),
],
})ConvertKit 提供文档的节点和标记 schema;PagesTableKit 的 TableKit 提供分页安全的表格。ConvertKit 内置的 ConvertTableKit 不是分页安全的,这就是我们在这里将其禁用的原因。
场景 B:Pages + DOCX 导入
在同一套栈的基础上再添加 ImportDocx 扩展。保持禁用 ConvertKit 的表格;PagesTableKit 的 TableKit 接受与 ConvertKit 表格相同的 DOCX 单元格属性,因此导入的表格会随着分页正确渲染。
import { Editor } from '@tiptap/core'
import { ConvertKit } from '@tiptap-pro/extension-convert-kit'
import { ImportDocx } from '@tiptap-pro/extension-import-docx'
import { TableKit } from '@tiptap-pro/extension-pages-tablekit'
import { Pages } from '@tiptap-pro/extension-pages'
const editor = new Editor({
extensions: [
ConvertKit.configure({ table: false }),
TableKit,
ImportDocx.configure({
/* token, … */
}),
Pages.configure({
/* 页面格式、边距等 */
}),
],
})支持的内容
通用行为(两种场景都适用)
- 分页安全的表格渲染。 表格位于页面内容区域内,不会在水平方向溢出。
- 保留列比例。 当每个单元格都带有
colwidth时,列会按比例缩小以适配页面。10 % / 40 % / 50 % 的列分配在任何页面宽度下都会渲染为 10 / 40 / 50。 - 行高行为。
heightRule: "exact":行会按声明的高度渲染,并裁剪溢出的内容。heightRule: "atLeast"(或未设置):当内容或更窄的列本会导致裁剪时,行会在垂直方向增长。
- 实时更新。 增加、删除或重新排序单元格的编辑会立即重新布局该行。
仅 DOCX 专属行为(场景 B)
当你的文档内容由 DOCX 导入器生成时,这些额外行为会自动启用。你不需要单独配置它们;如果转换器输出了该属性,PagesTableKit 就会遵守它。
- 遵守已声明的 DOCX 宽度。 如果 DOCX 表格作者设定的宽度大于页面,它会按比例缩小到内容区域,而不是溢出。
- DOCX 行高。 使用
w:trHeight且w:hRule="exact"时会裁剪;w:hRule="atLeast"(或缺失)时会增长。 - 保留窄的间距列。 DOCX 间距列(1–15 px)不会被放大成可见宽度。
- 负值 DOCX 缩进。 DOCX 中的负值
w:tblInd(Word 会把它渲染到纸张边缘的槽位/留白处)会保留到attrs.indent中,但会在视觉上被钳制为 0,防止表格推到页面边缘之外。 - 单元格背景、垂直对齐、每侧边框。 会从 DOCX 导入直接传递过来,无需额外处理。
不支持的内容
这些是有意设定的限制
这些不是 bug。它们是该功能明确且文档化的边界。如果你的工作流依赖下面任何一项,这个功能就不是合适的工具。
通用限制(两种场景都适用)
- 不带 Pages 扩展的编辑器。 PagesTableKit 是为 Pages 的分页布局设计的;它依赖 Pages 将行限制在页面内。在标准编辑器中,行无法正确渲染,过宽的表格会在水平方向溢出。请改用普通表格扩展。
- 手动编写且混合使用
colwidth/ 不使用colwidth的行。 当每个单元格都带有列宽时,才会触发按比例收缩行为。如果某些单元格带宽度而某些没有,列的渲染比例可能与你预期不同。 - 列宽拖拽控制柄。 支持来自
@tiptap/extension-table的拖拽调整大小,但最终渲染宽度可能会按比例而不是你拖到的精确像素值呈现,尤其是在每个单元格已经带有列宽时。
仅 DOCX 限制(场景 B)
- 浮动表格。 DOCX
w:tblpPr(相对于锚点并带文本环绕定位的表格)不会被导入器转换;浮动表格会按普通的纵向堆叠表格渲染。 - 与 Microsoft Word 表格布局的像素级一致。 Word 使用专有的布局算法,将固定和比例尺寸与内容测量混合在一起。对于使用 Word“自动调整为内容”设置创建的表格,可能会出现细微差异。
已知问题
行必须能放进单个页面
当表格行放不下当前页面时,Pages 会将整行作为一个原子单元移到下一页。这与 Microsoft Word 不同,Word 会在视觉上把很高的行跨页拆分。PagesTableKit 目前不支持行中间的分页拆分。
如果某一行的高度大于页面内容区域,那么即使把它移到下一页,它也仍然放不下:编辑器会继续尝试把它往后移动,并陷入无限循环。最终会导致无限分页循环和损坏的编辑器。
如何避免。 保持行高小于页面内容区域。尤其注意:
heightRule: "atLeast"的行:其内容可能无限增长。- 继承了非常高的精确高度行的 DOCX 导入:这些行是为比目标页面格式更大的纸张编写的。
- 单元格内嵌套的表格:这可能导致外层行比页面更高。
行内分页拆分在路线图中。ETA:待定。
预期会发生什么
通用(两种场景都适用)
- 表格位于页面内容区域内;精确高度行会裁剪,
atLeast行会增长。 - 每次事务都会生效;增加或删除单元格会立即重新布局该行。
- 超大的表格(成千上万行)在编辑时可能会带来明显的布局开销。如果遇到这种情况,可以考虑手动对大表格分页,或将其拆分到多个文档中。
仅 DOCX(场景 B)
- 导入时,DOCX 表格会保留其声明的宽度、行高、缩进、背景颜色以及每侧边框。
- 过宽的 DOCX 表格(Word 模板中常见的全宽表格)会在视觉上缩小以适配页面,而不是溢出。
- 渲染前不需要对导入的 DOCX JSON 做后处理;扩展会直接读取导入器生成的属性。
不要指望
通用(两种场景都适用)
- Pages 的替代品。 PagesTableKit 只负责表格。分页、页面容器、页眉和页脚都是 Pages 的职责。
- 来自你自定义 DOM 代码的列宽变更。 列宽来自 ProseMirror 文档。请通过
@tiptap/extension-table的命令(或你自己的事务)来改变它们,而不是直接写入dom.style。
仅 DOCX(场景 B)
- 往返一致性(round-trip identity)。 通过 Convert 管道导入再导出 DOCX 不能保证字节级完全一致。导入时会丢弃不支持的 DOCX 功能(浮动、某些表格样式)。
配置参考
PagesTableKit 导出一个单独的 TableKit 扩展,将 Table、TableRow、TableCell 和 TableHeader 打包在一起。
import { TableKit } from '@tiptap-pro/extension-pages-tablekit'
// 使用默认值
TableKit,每个打包的扩展都可以配置(或用 false 禁用),通过 TableKit.configure():
TableKit.configure({
table: { cellMinWidth: 1 }, // 来自 @tiptap/extension-table 的 Table 选项
tableRow: {
/* TableRow 选项 */
},
tableCell: {
/* TableCell 选项 */
},
tableHeader: false, // 完全禁用表头扩展
})PagesTableKit 没有任何独有的配置项;每个键都会透传到其底层扩展的标准选项。
相关内容
- 页面概览:PagesTableKit 所需的分页扩展。
- 表格中的页面:在 Pages 中编写表格的一般指南。
- ConvertKit:支持 DOCX 的编辑器套件;用于场景 B。
- 编辑器扩展(导入 DOCX):
ImportDocx扩展如何将 Word 内容导入你的编辑器。 - CSS 注入(导入):将 DOCX 样式目录提取为 CSS,以便在分页内容中保持一致的排版。