vue-pdf高亮
时间: 2025-05-20 09:46:44 浏览: 17
### 实现 Vue.js 中 PDF 高亮功能的方法
在 Vue.js 中实现 PDF 文档的高亮功能可以通过结合 `pdf.js` 和其他辅助库来完成。以下是详细的说明:
#### 1. **基础依赖**
为了实现 PDF 的加载和显示,可以使用 Mozilla 提供的开源库 `pdf.js`[^1]。该库支持解析和渲染 PDF 文件的内容。
安装 `pdf.js` 及其相关依赖项:
```bash
npm install pdfjs-dist --save
```
#### 2. **PDF 加载与渲染**
通过 `pdf.js` 获取 PDF 页面并将其绘制到 Canvas 上。这是实现高亮的基础步骤之一。
以下是一个简单的示例代码片段展示如何加载 PDF 并渲染第一页:
```javascript
import { getDocument } from 'pdfjs-dist';
export default {
data() {
return {
pdfDoc: null,
currentPage: 1,
};
},
methods: {
async loadPdf(url) {
this.pdfDoc = await getDocument(url).promise;
this.renderPage(this.currentPage);
},
renderPage(num) {
const page = this.pdfDoc.getPage(num);
const canvas = document.getElementById('pdfCanvas');
const ctx = canvas.getContext('2d');
const viewport = page.getViewport({ scale: 1.5 });
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = {
canvasContext: ctx,
viewport: viewport,
};
page.render(renderContext);
}
},
};
```
#### 3. **文本提取与匹配**
要实现高亮功能,需要先从 PDF 中提取文本内容,并找到目标关键字的位置。`pdf.js` 支持通过 API 提取每页的文字信息。
下面是如何提取文字的一个例子:
```javascript
async highlightText(pageNumber, keyword) {
const page = await this.pdfDoc.getPage(pageNumber);
// Extract text content
const textContent = await page.getTextContent();
const keywordsPositions = [];
textContent.items.forEach((item, index) => {
if (item.str.includes(keyword)) {
keywordsPositions.push(index); // Record positions of matched items.
}
});
console.log(`Keyword "${keyword}" found at indices ${keywordsPositions}`);
}
```
#### 4. **应用高亮效果**
一旦找到了关键字所在位置,就可以利用 SVG 或者 Canvas 绘制矩形框覆盖这些区域以达到视觉上的高亮效果。这里提供一种基于 Canvas 的方法:
修改之前的 `renderPage()` 函数,在原有基础上增加高亮逻辑:
```javascript
page.render(renderContext).then(() => {
// Highlight logic after rendering the base layer
this.highlightKeywords(ctx, pageNumber, keyword);
});
highlightKeywords(canvasCtx, pageNumber, keyword) {
const page = this.pdfDoc.getPage(pageNumber);
page.getTextContent().then(textContent => {
let lastY = -Infinity; // Track previous line's Y coordinate to merge rectangles.
textContent.items.forEach(item => {
if (!item.str.toLowerCase().includes(keyword.toLowerCase())) return;
const rect = item.transform.slice(4); // Get bounding box coordinates.
const xScaleFactor = canvasCtx.canvas.width / page.view[2];
const yScaleFactor = canvasCtx.canvas.height / page.view[3];
const scaledRect = [
rect[4] * xScaleFactor,
rect[5] * yScaleFactor,
Math.abs(rect[0]) * xScaleFactor,
Math.abs(rect[1]) * yScaleFactor,
];
if (scaledRect[1] === lastY && scaledRect[0] !== Infinity) {
prevScaledRect[2] += scaledRect[2]; // Merge horizontally adjacent rects.
} else {
drawHighlight(prevScaledRect); // Draw accumulated rectangle before resetting it.
prevScaledRect = [...scaledRect];
lastY = scaledRect[1];
}
function drawHighlight([x, y, width, height]) {
if (!(width > 0 && height > 0)) return;
canvasCtx.fillStyle = 'rgba(255, 255, 0, 0.5)';
canvasCtx.fillRect(x, y, width, height);
}
});
drawHighlight(prevScaledRect); // Ensure final rectangle gets drawn too.
});
}
```
以上代码会遍历所有包含给定关键词的文本块,并在其周围画上半透明黄色背景作为高亮标记。
---
### 注意事项
- 如果希望更复杂的交互体验(比如点击跳转特定页面),还可以参考引用中的 iframe 控制技巧[^2]。
- 对于大型项目建议考虑封装成独立组件以便重用和维护方便。
阅读全文
相关推荐


















