Word复制到Plate后无法保存:fontSize和textIndent问题

问题

最近在使用 Plate 富文本编辑器时遇到一个问题。

从 Word 里复制内容到 Plate,文字、颜色、表格看起来都正常,但是点击保存就报错:

fontSize 不是安全字号

包含未授权属性:['textIndent']

折腾几次后才发现,这些其实都是同一个问题:Word 复制过来的格式,浏览器和 Plate 可以正常显示,但不一定符合后端规定的 Plate 文档格式。

每天一个富文本小 bug :sweat_smile:

fontSize 为什么无法保存

Word 使用的字号单位一般是 pt。

例如从 Word 复制一个 10.5 磅的文字,进入 Plate 后可能变成:

{
  "text": "麻黄",
  "fontSize": "10.5pt"
}

但是后端的 Plate 校验只允许:px、em、rem、%,所以编辑器里看起来没问题,保存时后端却认为 10.5pt 是不安全字号。

解决方法是保存前将 pt 转成 px,换算关系:1pt = 4/3px

不能直接删除 fontSize,否则虽然可以保存,但从 Word 复制过来的字号也丢了。

未授权属性 textIndent 又是什么

处理完字号后,又遇到了:

包含未授权属性:['textIndent']

textIndent 一般是 Word 里的首行缩进或者段落缩进,也是plate不支持的,如果当前业务不需要保留 Word 的首行缩进,可以在保存前直接删除textIndent

为什么 textIndent 每次报错的 value 都不一样

第一次报:value[13] 包含 textIndent,改完代码变成value[15] 包含 textIndent,改了一遍又一遍发现不对了

因为Word 里的表格复制到 Plate 后,结构很深:

table
  → tr
    → td
      → p
        → text

前面只要多一个空行或者标题,后面的数组下标就会变化,所以不能根据具体的 value[13] 修,应该递归检查整份 Plate 文档,去掉所有textIndent

总结

这个问题的核心不是 Plate 不能粘贴 Word,而是下面几层支持的格式不完全一样:

Word 格式
→ 浏览器剪贴板
→ Plate JSON
→ 后端允许的 Plate JSON

浏览器比较宽松,10.5pt 和 textIndent 都能正常显示;后端为了安全和数据稳定,只接受白名单里的属性。

拓展

plate仓库 GitHub - udecode/plate: Rich-text editor with AI and shadcn/ui · GitHub
plate官网 https://platejs.org/