Vue 3 是一个现代的前端框架,而 PDF.js 是由 Mozilla 开发的一个用于在浏览器中渲染 PDF 文件的强大工具。将 Vue 3 与 PDF.js 集成,可以为用户提供流畅的文档查看和处理体验。本文将详细介绍如何在 Vue 3 中集成 PDF.js,并实现基本的文档查看功能以及扩展的处理能力。
首先,确保你已经安装了 Node.js 和 npm/yarn。然后使用 Vue CLI 或 Vite 创建一个新的 Vue 3 项目。
# 使用 Vue CLI 创建项目
vue create vue-pdf-viewer
# 或者使用 Vite 创建项目
npm create vite@latest vue-pdf-viewer --template vue
进入项目目录并启动开发服务器:
cd vue-pdf-viewer
npm install
npm run serve
PDF.js 可以通过 npm 安装:
npm install pdfjs-dist
pdfjs-dist
是 PDF.js 的官方 npm 包,它包含了核心库和必要的 Web Worker 文件。
PDF.js 提供了一个 getDocument
方法,用于加载 PDF 文件。我们可以通过 URL 或 Blob 加载 PDF。
import { ref, onMounted } from 'vue';
import * as PDFJS from 'pdfjs-dist';
export default {
setup() {
const pdfPages = ref([]);
const canvasList = [];
const loadPdf = async (url) => {
try {
const loadingTask = PDFJS.getDocument(url);
const pdf = await loadingTask.promise;
for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber++) {
const page = await pdf.getPage(pageNumber);
const viewport = page.getViewport({ scale: 1.5 });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: context, viewport }).promise;
canvasList.push(canvas);
pdfPages.value.push(canvas.toDataURL());
}
} catch (error) {
console.error('Error loading PDF:', error);
}
};
onMounted(() => {
loadPdf('https://example.com/sample.pdf'); // 替换为实际的 PDF URL
});
return { pdfPages };
},
};
在模板中展示加载的 PDF 页面:
<template>
<div v-for="(page, index) in pdfPages" :key="index">
<img :src="page" alt="PDF Page" />
</div>
</template>
为了支持用户上传本地 PDF 文件,我们可以添加一个文件输入框,并使用 FileReader 将文件转换为 Blob。
<template>
<input type="file" @change="handleFileChange" accept=".pdf" />
</template>
<script>
export default {
methods: {
handleFileChange(event) {
const file = event.target.files[0];
if (file) {
const fileReader = new FileReader();
fileReader.onload = () => {
this.loadPdf(fileReader.result); // 调用 PDF 加载方法
};
fileReader.readAsArrayBuffer(file);
}
},
},
};
</script>
通过按钮或分页组件,用户可以跳转到指定的 PDF 页面。
const currentPage = ref(1);
const renderPage = async (pageNumber) => {
const page = await pdfDoc.getPage(pageNumber);
const viewport = page.getViewport({ scale: 1.5 });
const canvas = document.getElementById('pdf-canvas');
const context = canvas.getContext('2d');
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: context, viewport }).promise;
};
// 在模板中添加按钮
<button @click="currentPage--">上一页</button>
<button @click="currentPage++">下一页</button>
启用 Web Worker
PDF.js 默认会使用 Web Worker 来解析 PDF 文件,这可以避免阻塞主线程。如果你需要自定义 Worker,请确保正确配置:
PDFJS.GlobalWorkerOptions.workerSrc = '/node_modules/pdfjs-dist/build/pdf.worker.min.js';
按需加载页面
对于大文件,建议只加载当前显示的页面,而不是一次性加载所有页面。
跨域问题
如果加载的是远程 PDF 文件,请确保服务器支持 CORS。
以下是 PDF 加载与渲染的基本流程图:
flowchart TD A[初始化] --> B{是否有 PDF 文件} B --是--> C[加载 PDF 文件] C --> D[解析 PDF 文档] D --> E[遍历每一页] E --> F[获取页面内容] F --> G[设置缩放比例] G --> H[渲染到 Canvas] H --> I[完成渲染] B --否--> J[等待用户上传文件]