如何在pdf.js viewer中恢复并渲染已存储的JSON格式注释?
在PDF.js Viewer中重载页面后恢复并渲染注释的解决方案
核心问题分析
直接调用PDFViewerApplication.pdfDocument._transport.annotationStorage.setAll()无效,主要是执行时机错误或注释数据处理不当——PDF文档和注释系统未完成初始化时调用该方法,无法将注释绑定到文档并触发渲染。
分步解决方案
1. 确保注释JSON格式匹配
先确认你保存的注释JSON和getAll()返回的结构完全一致:它应该是一个以注释ID为键、注释对象为值的对象,示例结构如下:
{ "annotation-id-1": { "id": "annotation-id-1", "pageIndex": 0, "rect": [50, 50, 200, 100], "content": "这是一条注释", "type": "text" // 其他注释相关字段 }, "annotation-id-2": { // ... } }
2. 选择正确的执行时机
必须等待PDF文档完全加载、注释系统初始化完成后,再执行注释恢复逻辑。通过PDFViewerApplication.eventBus监听documentloaded事件是可靠的时机。
3. 完整代码示例
从JSON文件加载并恢复注释
window.addEventListener('load', async function() { // 设置默认PDF(按需保留) PDFViewerApplicationOptions.set('defaultUrl', 'compressed.tracemonkey-pldi-09.pdf'); // 1. 加载保存的注释JSON文件 const annotationRes = await fetch('/path/to/your/saved-annotations.json'); const savedAnnotations = await annotationRes.json(); // 2. 监听文档加载完成事件,执行恢复逻辑 PDFViewerApplication.eventBus.on('documentloaded', async function() { const annotationStorage = PDFViewerApplication.pdfDocument._transport.annotationStorage; // 可选:清空现有注释(避免新旧注释冲突) await annotationStorage.clear(); // 3. 恢复保存的注释 await annotationStorage.setAll(savedAnnotations); // 4. 强制重新渲染注释层 if (PDFViewerApplication.annotationLayer) { PDFViewerApplication.annotationLayer.render(); } }); });
若注释存储在本地(如localStorage)
如果注释是存在localStorage而非文件,可简化为:
window.addEventListener('load', function() { PDFViewerApplicationOptions.set('defaultUrl', 'compressed.tracemonkey-pldi-09.pdf'); PDFViewerApplication.eventBus.on('documentloaded', async function() { const savedAnnotations = JSON.parse(localStorage.getItem('pdf-annotations')); if (!savedAnnotations) return; const annotationStorage = PDFViewerApplication.pdfDocument._transport.annotationStorage; await annotationStorage.setAll(savedAnnotations); PDFViewerApplication.annotationLayer.render(); }); });
常见问题排查
- API路径问题:不同版本的PDF.js可能调整内部API路径,若
_transport.annotationStorage无效,可检查PDFViewerApplication.pdfDocument.annotationStorage是否可用。 - CORS错误:加载本地JSON文件时需通过HTTP服务器访问(如
localhost),直接打开本地HTML文件会触发跨域限制。 - 注释未渲染:若注释已存入storage但未显示,可尝试手动触发
annotationLayer.render(),或检查注释的pageIndex是否与当前PDF页面匹配。
内容的提问来源于stack exchange,提问作者Phemelo Khetho
相关产品推荐
相关产品推荐

