这类需求我在业务里接过不止一次:用户上传一份PDF,希望在线上文档编辑器里直接打开,还要能圈出重点、在旁边写几句批注,提交后高亮和注释都能保存下来。标题虽然写的是“xhEditor PDF导入支持文本高亮和注释”,但把“PDF导入”“文本高亮”“注释”三个点拆开,每一块都有不少隐藏的坑。
先把结论放前面:如果只是把PDF渲染成canvas图片塞进编辑器,等于在PPT里贴了一页纸,看起来是那么回事,但文字没法选中,标注没法落库,一刷新全丢;真正能做的是用PDF解析库取出里面的文本内容,再转成可编辑的HTML,让高亮与注释以DOM标签的形态和正文一起保存。这套方案不止xhEditor能用,换成UEditor、wangEditor甚至自己写的contenteditable都成立。
下面按我实际落地的思路,把这套链路完整写一遍。
1. 先拆需求:PDF、富文本、批注这三样东西要怎么合体
接到“PDF导入编辑器,支持文本高亮和注释”这类需求时,最忌讳的是直接开始写代码。先要把交付物定义清楚:到底是要“像在PDF阅读器里一样批注原PDF”,还是“把PDF的文字变成编辑器里的正文,再对正文做标注”。
这两者的技术路线完全不同。前者是典型的PDF预览批注系统,需要以页面为底图,在上面叠加高亮矩形、注释图标,保存的是坐标和文本片段;后者是富文本编辑器能力扩展,核心在于把PDF里的文本正确提取出来,保持可编辑性,高亮和注释都只是对文本节点做包装。
我采用的路线是后者,原因是多数后台系统的诉求其实是“文档内容入库、审核、二次编辑”,而不是做一份可以回写的PDF审阅文件。两种方案的取舍如下:
| 方案 | 可编辑性 | 数据保存 | 版式还原 | 开发复杂度 |
|---|---|---|---|---|
| PDF整页转图片插入 | 差,仅能看图 | 差,保存的是图片 | 高 | 低 |
| PDF.js渲染+坐标浮层批注 | 差,批注与正文不联动 | 一般,需要存坐标JSON | 高 | 高 |
| PDF解析成富文本并做标签标注 | 好,文字本身就是HTML | 好,高亮注释随HTML存储 | 中低 | 中 |
从业务可维护性角度看,第三种最划算:xhEditor初始化时绑定的是textarea,textarea的值就是一段HTML。我把带高亮标签的正文写进textarea,用户点保存,高亮和注释天然跟着内容走,不需要额外的关联表,也没那么容易出现“正文改了,批注坐标还指在原来的位置上”这种尴尬问题。
这个方案也有它的边界:它不适合要严格保留原始PDF排版的场景,比如多栏杂志、复杂表单、图文混排的设计稿。单栏的合同、论文、报告、通知类PDF是它的主场,由于导入后正文会变成可编辑文本,原版的字体、缩进、表格边框大概率是保留不住,这一点要在文档里向用户说清楚。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. PDF文本提取:从pdf.js到一份不丢字的可编辑正文
2.1 搭好pdf.js的运行前提
PDF文本提取我选择pdf.js,它对中文的兼容性比mupdf.js要稳,作者维护也勤快。前端用的时候别只引入主库,worker和CMap目录这两样
