如何在Vite+React项目中为react-pdf Viewer添加PDF高亮批注
实现react-pdf-viewer的本地永久高亮批注功能
要在Vite+React项目里用react-pdf-viewer实现无需数据库的永久高亮,你需要正确配置highlight插件并在本地存储高亮数据(组件状态+localStorage)。以下是修改后的完整方案:
核心修改点
- 导入并初始化
highlightPlugin,绑定高亮数据的读写逻辑 - 用组件状态存储高亮内容,结合
localStorage实现页面刷新后高亮不丢失 - 将highlight插件加入Viewer的插件列表,启用高亮交互
修改后的完整代码
import React, { useState, useEffect } from "react"; import { Worker, Viewer } from "@react-pdf-viewer/core"; import { ExcelRenderer, OutTable } from "react-excel-renderer"; import { defaultLayoutPlugin } from "@react-pdf-viewer/default-layout"; import { highlightPlugin } from "@react-pdf-viewer/highlight"; // 新增导入highlight插件 import "@react-pdf-viewer/highlight/lib/styles/index.css"; import "@react-pdf-viewer/core/lib/styles/index.css"; import "@react-pdf-viewer/default-layout/lib/styles/index.css"; import { backendBaseUrl } from "../config"; function DocumentDrawer({ isOpen, toggle, viewFile }) { const newPdfPlugin = defaultLayoutPlugin(); const [fileType, setFileType] = useState(null); const [excelData, setExcelData] = useState(null); // 存储当前PDF的高亮数据,初始值从localStorage读取或为空数组 const [highlights, setHighlights] = useState([]); // 初始化highlight插件,绑定数据更新逻辑 const highlightPluginInstance = highlightPlugin({ highlights, onHighlightChange: (newHighlights) => { setHighlights(newHighlights); // 按文件名存储高亮,确保不同PDF的高亮独立保存 localStorage.setItem(`pdf-highlights-${viewFile}`, JSON.stringify(newHighlights)); }, }); // 切换PDF文件时,加载对应文件的历史高亮 useEffect(() => { if (!viewFile) return; const savedHighlights = localStorage.getItem(`pdf-highlights-${viewFile}`); setHighlights(savedHighlights ? JSON.parse(savedHighlights) : []); }, [viewFile]); // 补充文件类型识别逻辑(原代码未实现,确保能正确区分PDF/Excel) useEffect(() => { if (viewFile) { const ext = viewFile.split('.').pop().toLowerCase(); setFileType(ext === 'pdf' ? 'pdf' : 'excel'); // 处理Excel文件渲染 if (ext === 'excel') { ExcelRenderer(`${backendBaseUrl}/api/documents/${viewFile}`, (err, resp) => { if (err) console.error(err); else setExcelData(resp); }); } } }, [viewFile]); return ( <div className={`sidebar_content_viewer ${isOpen ? "open" : ""}`}> <button className="btn ms-5 btn-primary close-button" onClick={toggle}> Close </button> <div className="slider_inner_contentview"> <div className="file_container"> {fileType === "pdf" && ( <Worker workerUrl="https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.worker.min.js"> <Viewer fileUrl={`${backendBaseUrl}/api/documents/${viewFile}`} plugins={[newPdfPlugin, highlightPluginInstance]} // 启用highlight插件 defaultScale={1.2} preload={true} /> </Worker> )} {/* 渲染Excel文件 */} {fileType === "excel" && excelData && ( <OutTable data={excelData} columns={excelData.headers} /> )} </div> </div> </div> ); } export default DocumentDrawer;
关键说明
- 高亮持久化:用户添加/删除高亮时,
onHighlightChange会同步更新组件状态并将数据存入localStorage,刷新页面或切换回同一PDF时会自动加载历史高亮 - 插件生效条件:必须将
highlightPluginInstance加入Viewer的plugins数组,否则高亮交互和样式都不会生效 - 文件隔离:通过
pdf-highlights-${viewFile}作为localStorage的键,保证不同PDF的高亮数据不会互相覆盖
内容的提问来源于stack exchange,提问作者Dark_Shadow
相关产品推荐
相关产品推荐

