Vue 3与PDF.js集成:文档查看与处理功能

2025-04发布7次浏览

Vue 3 是一个现代的前端框架,而 PDF.js 是由 Mozilla 开发的一个用于在浏览器中渲染 PDF 文件的强大工具。将 Vue 3 与 PDF.js 集成,可以为用户提供流畅的文档查看和处理体验。本文将详细介绍如何在 Vue 3 中集成 PDF.js,并实现基本的文档查看功能以及扩展的处理能力。


一、环境准备

1. 创建 Vue 3 项目

首先,确保你已经安装了 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

2. 安装 PDF.js

PDF.js 可以通过 npm 安装:

npm install pdfjs-dist

pdfjs-dist 是 PDF.js 的官方 npm 包,它包含了核心库和必要的 Web Worker 文件。


二、基本功能实现:PDF 文档加载与渲染

1. 加载 PDF 文件

PDF.js 提供了一个 getDocument 方法,用于加载 PDF 文件。我们可以通过 URL 或 Blob 加载 PDF。

示例代码:加载远程 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 };
  },
};

2. 渲染 PDF 页面

在模板中展示加载的 PDF 页面:

<template>
  <div v-for="(page, index) in pdfPages" :key="index">
    <img :src="page" alt="PDF Page" />
  </div>
</template>

三、高级功能扩展:文档处理与交互

1. 支持本地文件上传

为了支持用户上传本地 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>

2. 添加页面导航功能

通过按钮或分页组件,用户可以跳转到指定的 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>

四、性能优化与注意事项

  1. 启用 Web Worker
    PDF.js 默认会使用 Web Worker 来解析 PDF 文件,这可以避免阻塞主线程。如果你需要自定义 Worker,请确保正确配置:

    PDFJS.GlobalWorkerOptions.workerSrc = '/node_modules/pdfjs-dist/build/pdf.worker.min.js';
    
  2. 按需加载页面
    对于大文件,建议只加载当前显示的页面,而不是一次性加载所有页面。

  3. 跨域问题
    如果加载的是远程 PDF 文件,请确保服务器支持 CORS。


五、流程图:PDF 加载与渲染逻辑

以下是 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[等待用户上传文件]