如何使用react-pdf-viewer实现PDF段落/句子的程序化高亮?
解决react-pdf-viewer段落/句子高亮问题
你当前使用searchPlugin的highlight方法仅支持单个搜索词高亮,要实现段落、句子级别的高亮,需结合highlightPlugin与PDF文本定位能力完成,具体方案如下:
1. 替换插件并初始化
移除searchPlugin,改用highlightPlugin,确保依赖引入正确:
import PropTypes from "prop-types"; import { Worker, Viewer, SpecialZoomLevel } from "@react-pdf-viewer/core"; import { highlightPlugin } from "@react-pdf-viewer/highlight"; import "@react-pdf-viewer/highlight/lib/styles/index.css"; import * as pdfjsLib from "pdfjs-dist"; import "@react-pdf-viewer/default-layout/lib/styles/index.css"; import { useEffect, useState, useRef } from "react";
2. 完整实现代码
通过pdfjs API获取PDF每页文本,匹配目标段落的位置后生成高亮数据:
export default function PDFView({ pdfUrl, highlightedText }) { const highlightPluginInstance = highlightPlugin(); const { addHighlights } = highlightPluginInstance; const viewerRef = useRef(null); const [documentLoaded, setDocumentLoaded] = useState(false); useEffect(() => { if (!documentLoaded || !highlightedText) return; const fetchAndHighlight = async () => { // 加载PDF文档 const loadingTask = pdfjsLib.getDocument({ url: pdfUrl }); const pdfDoc = await loadingTask.promise; const highlights = []; // 遍历每页查找目标文本 for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) { const page = await pdfDoc.getPage(pageNum); const textContent = await page.getTextContent(); // 拼接当前页文本,方便匹配 const pageText = textContent.items.map(item => item.str).join(" "); // 匹配目标段落(可根据需求替换为精确匹配逻辑) if (pageText.includes(highlightedText)) { // 收集匹配到的文本片段坐标 const matchedSegments = textContent.items.filter(item => highlightedText.includes(item.str)); matchedSegments.forEach(item => { highlights.push({ pageIndex: pageNum - 1, // react-pdf-viewer使用0起始页码 rects: [ { x: item.transform[4], y: item.transform[5], width: item.width, height: item.height, }, ], text: item.str, id: `${pageNum}-${Math.random()}`, // 生成唯一标识 }); }); } } // 批量添加高亮 addHighlights(highlights); }; fetchAndHighlight(); }, [documentLoaded, highlightedText, pdfUrl, addHighlights]); return ( <div className="border-solid border-2 rounded-md border-slate-300 h-screen w-auto overflow-auto overscroll-contain"> <Worker workerUrl={`https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.js`}> <Viewer ref={viewerRef} fileUrl={pdfUrl} defaultScale={SpecialZoomLevel.PageFit} onDocumentLoad={() => setDocumentLoaded(true)} plugins={[highlightPluginInstance]} /> </Worker> </div> ); } PDFView.propTypes = { pdfUrl: PropTypes.string.isRequired, highlightedText: PropTypes.string.isRequired, };
关键细节说明
- 文本匹配逻辑:示例用
includes做模糊匹配,若需精确匹配完整段落,可调整为按换行分割文本或用正则表达式匹配。 - 坐标处理:从
textContent.items中提取文本片段的坐标,若要高亮完整连续段落,可将相邻文本片段的rect合并为一个大区域。 - 跨页处理:如果目标段落跨多页,循环遍历每页时会自动在对应页面生成高亮。
内容的提问来源于stack exchange,提问作者neil_ruaro
相关产品推荐
相关产品推荐

