利用vue-pdf-embed实现PDF文件的预览

前言

在前端开发里,有时候会遇到需要在网页中展示 PDF 文档预览功能,比如合同 ERP、销售 CRM、内部文档 CMS 管理系统,内置 PDF 文件在线预览功能。Vue 3 作为流行的 JavaScript 框架,为开发者提供了强大的工具和生态系统。而 pdf.js 是 Mozilla 开发的一个基于 HTML5 的开源 PDF 渲染库,它能让我们在浏览器中无需借助第三方插件就可以直接展示 PDF 文件。本文会详细阐述如何在 Vue 项目里使用vue-pdf-embed 来展示 PDF 文档,让网页具备出色的文档展示能力。

一、概述

1.1 关于 PDF.js

PDF.js 是由 Mozilla 开发的一款开源 JavaScript 库,旨在通过纯前端技术实现 PDF 文件的在线预览,无需依赖任何浏览器插件。其核心架构基于 HTML5 与 Canvas 技术,结合 JavaScript 解析 PDF 文件内容,实现跨浏览器兼容性。该库采用分层设计,主要包括 PDF 解析层、页面渲染层和用户交互层。PDF.js 通过 Web Worker 处理 PDF 解析任务,避免阻塞主线程,从而提升性能。其渲染机制采用 Canvas 绘制页面内容,并通过视口适配技术实现页面缩放与滚动,确保在不同设备和分辨率下的良好显示效果。

一般来说,要查看 PDF 文档,我们需要一个 PDF 阅读器软件,而通过 PDF.js 可以在浏览器中直接显示和处理 PDF 文档,无论是在线浏览、存档或者其他基于 PDF 的功能都可以实现。

pdf.js官网:mozilla.github.io/pdf.js/

1.2 关于 vue-pdf-embed

作为基于 Vue 生态的组件,vue-pdf-embed 是一个专为 Vue 设计的PDF 查看器组件,底层基于 Mozilla 强大的 PDF.js 引擎构建,但去除了所有不必要的 UI 和复杂性,为开发者提供了在 Web 应用中无缝展示PDF文档的完整能力。这个组件通过创新的技术架构和优化的渲染机制,彻底改变了传统PDF嵌入的局限性。而且 vue-pdf-embed 提供了更丰富的功能,支持密码保护文档、文本选择和搜索、完整的注释层显示、灵活的页面控制(缩放、旋转)以及出色的跨设备响应式性能。

功能特性 传统iframe方案 vue-pdf-embed方案
文本选择功能 ❌ 无法实现 ✅ 完美支持
文档搜索能力 ❌ 功能缺失 ✅ 内置实现
注释层显示 ❌ 不支持 ✅ 可选开启
页面精确控制 ❌ 限制较多 ✅ 灵活配置
性能表现 ❌ 加载缓慢 ✅ 优化出色

1.2 核心亮点

在众多 PDF 显示方案中,vue-pdf-embed 脱颖而出,原因在于它的零配置开箱即用特性。无需复杂的设置过程,只需简单安装即可开始使用。更重要的是,它支持多种PDF数据源,包括URL链接、Base64编码、二进制数据等,满足各种实际应用场景的需求。

核心价值 技术优势
零配置开箱即用 基于PDF.js,无需复杂的对等依赖或额外配置,简化安装和使用过程
性能极致优化 Web Worker支持,内存占用合理
开发体验提升 TypeScript原生支持,完整类型定义
精确渲染控制 在Vue应用中实现对PDF文档渲染的精准掌控,开发者可根据需求灵活展示文档内容
密码保护支持 能够处理密码保护的PDF文档,确保用户在有权限的情况下查看文档内容
文本层与注释层 包含文本层,使文档可搜索和选择,提升用户交互体验。同时具备注释层,支持注释和链接显示
浏览器直接使用 可直接在浏览器中使用,方便快捷地集成到项目中

二、快速上手 🚀

2.1 安装依赖

万事开头难,但 vue-pdf-embed 的起步却异常简单。首先,确保有一个正在开发的Vue 3项目。我用的是Vite + Vue 3 + TypeScript的组合,这也是目前最主流和高效的开发栈。

进入项目根目录,执行安装命令:

bash 复制代码
# npm
npm install vue-pdf-embed

# yarn
yarn add vue-pdf-embed

# pnpm(推荐)
pnpm add vue-pdf-embed

注意:pdfjs-dist 是核心依赖,必须同时安装,版本建议选择3.x+以兼容 Vue3。

2.2 引入插件

在安装完成后,我们需要在项目中引入并配置 vue-pdf-embed,在需要使用该功能的 Vue 文件中直接引入:

javascript 复制代码
import VuePdfEmbed from 'vue-pdf-embed'

// 可选样式文件,增强显示效果(如果需要支持文本选择和注释交互)
import 'vue-pdf-embed/dist/styles/annotationLayer.css'
import 'vue-pdf-embed/dist/styles/textLayer.css'

vue-pdf-embed 依赖 pdfjs-dist 进行底层解析,如果未正确配置 Web Worker 的路径,会导致解析引擎初始化失败。在引入组件的同时,手动引入 pdfjs-dist 并配置 workerSrc,建议在组件渲染前完成此设置:

javascript 复制代码
import VuePdfEmbed from 'vue-pdf-embed'
import * as PDFJS from 'pdfjs-dist'

// 配置 worker 路径(Vite 环境下推荐使用 new URL 的方式)
PDFJS.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.mjs',
  import.meta.url
).toString()

2.3 基础用法示例

全局注册后,在任意组件中直接使用,仅需几行核心代码,即可实现 PDF 预览。理论说再多,不如直接看代码。

html 复制代码
<script setup lang="ts">
import VuePdfEmbed from 'vue-pdf-embed'

const pdfUrl = ref('https://cdn.jsdelivr.net/gh/mozilla/pdf.js/web/compressed.tracemonkey-pldi-09.pdf');
</script>

<template>
 <VuePdfEmbed :source="pdfUrl" />
</template>

就是这么简单!几行代码就能在页面中嵌入一个完整的PDF查看器。

三、核心功能深度解析

3.1 灵活的页面控制

在文档管理系统中,PDF 预览是核心功能之一。vue-pdf-embed 通过 page 属性可以指定显示特定页码或页码范围,满足不同场景需求:

javascript 复制代码
// 显示特定页面
<VuePdfEmbed :page="3" :source="pdfSource" />

// 显示多个页面
<VuePdfEmbed :page="[1, 5, 8]" :source="pdfSource" />

3.2 加载状态与错误处理

html 复制代码
<script setup lang="ts">
import VuePdfEmbed from 'vue-pdf-embed'
import { PDFDocumentProxy} from "pdfjs-dist/types/src/display/api";

const pdfUrl = ref('https://cdn.jsdelivr.net/gh/mozilla/pdf.js/web/compressed.tracemonkey-pldi-09.pdf');

// PDF加载完成时回调
const handleDocumentLoaded = (pdfDocument: PDFDocumentProxy) => {
  console.log('PDF文档加载成功,总页数:', pdfDocument.numPages);
  // 这里可以做一些初始化操作,比如更新总页数到状态管理
};

// 加载失败回调
const handleLoadError = (error: Error) => {
  console.error('PDF文档加载失败:', error);
  // 这里可以给用户一个友好的错误提示,比如"文档加载失败,请重试或检查文件"
};

</script>

<template>
 <VuePdfEmbed :source="pdfUrl" @loaded="handleDocumentLoaded" @error="handleLoadError" :width="1400" />
</template>

PDFDocumentProxy 是 PDF.js 库提供的一个核心对象,它代表了一个已经加载的 PDF 文档,通常会在 PDF 文件加载完成后的回调事件中获取到它。

核心属性与用法 简要说明
numPages 这是最常用的属性,用于获取当前 PDF 文档的总页数
fingerprint PDF 文档的唯一指纹标识
getPage(pageNumber) 传入页码,返回一个 Promise。 解析后得到指定页的 PDFPageProxy 对象,用于进一步渲染或获取页面尺寸等信息
destroy() 销毁该文档对象,释放相关内存

3.3 加载进度跟踪

html 复制代码
<script setup lang="ts">
import VuePdfEmbed from 'vue-pdf-embed'
import { OnProgressParameters } from "pdfjs-dist/types/src/display/api";

const pdfUrl = ref('https://cdn.jsdelivr.net/gh/mozilla/pdf.js/web/compressed.tracemonkey-pldi-09.pdf');

const handleProgress = (progress: OnProgressParameters) => {
  console.log('加载进度:', progress)
};

const handleRenderingFinished = () => {
  console.log('PDF文档渲染完成');
};

// 文档渲染失败回调
const handleRenderingFailed = (error: Error) => {
  console.error('PDF文档渲染失败:', error);
};

</script>

<template>
  <VuePdfEmbed
    ref="vuePdfRef"
    :source="pdfUrl"
    @progress="handleProgress"
    @renderingFailed="handleRenderingFailed"
    @rendered="handleRenderingFinished" />
</template>

3.4 加密文档处理

当PDF文件需要密码保护时,vue-pdf-embed 也能优雅地处理:

html 复制代码
<script setup>
import VuePdfEmbed from 'vue-pdf-embed'

const handlePasswordRequest = (event) => {
  const password = prompt('请输入PDF密码:')
  if (password) {
    event.callback(password)
  }
}
</script>

<template>
  <VuePdfEmbed 
    :source="pdfSource"
    @password-requested="handlePasswordRequest"
  />
</template>

四、API 参考手册

4.1 属性

通过简单的属性(Props)来精确控制 PDF 的展示效果

属性 类型 候选值 简要说明
source 文档源,支持 URL 链接、Base64 编码、二进制数据等
width number 自定义渲染的宽度
height number 自定义渲染的高度
page number number[] 指定显示的页码,不指定则显示所有页
scale number 页面的缩放比例
rotation number 0、90、180、270 旋转角度,比如0就是不旋转,+90,-90 就是水平旋转
textLayer boolean 是否启用文本层,允许用户在网页中复制、搜索 PDF 里的文字
annotationLayer boolean 是否启用注释层,显示 PDF 中的超链接、备注等交互元素
linkService 文档导航服务
imageResourcesPath string 注释层中使用的图标路径

4.2 事件处理机制

vue-pdf-embed 提供完整的事件系统,能够监控 PDF 加载和渲染的各个环节:

事件名 简要说明
internal-link-clicked 内部链接被点击时触发
loaded PDF 文档加载完成时触发
loading-failed PDF 加载失败时触发
password-requested 需要密码才能打开 PDF 时触发
progress 跟踪文档加载进度
rendered 文档渲染完成时触发
rendering-failed 文档渲染失败时触发

4.3 方法

方法名 参数 简要说明
print(resolution, fileName, allPages) resolution:打印分辨率,默认300 fileName:文件名 allPages:是否打印所有页,默认值 false 通过浏览器打印文档
download(fileName) 下载文档

4.4 插槽

插槽名 简要说明
after-page 每页后需添加的内容
before-page 每页前需添加的内容

总结

vue-pdf-embed 是 Vue 3 生态中轻量、易用的 PDF 预览组件,基于 pdfjs-dist 封装,无需关注底层解析逻辑。作为 Vue 生态中 PDF 处理的标杆项目,通过持续的技术创新和生态建设,为开发者提供了简单、高效、可靠的 PDF 文档嵌入能力,是现代化 Web 应用中处理 PDF 文档的首选技术方案。

相关推荐
xkxnq1 小时前
第七阶段:企业级项目实战核心能力(118天)Vue项目缓存策略:接口缓存(内存+本地)+ 组件缓存+路由缓存组合方案
vue.js·spring·缓存
Exploring1 小时前
Hola 计算器 v1.0.1 发布:个税计算全面升级,劳务报酬也能算清楚了!
前端
Pan Zonghui1 小时前
个人开源技术博客前端
前端·开源
kyriewen2 小时前
我让AI替我写Git提交信息,老板以为我每天工作16小时
前端·javascript·git
简简单单就是我_hehe2 小时前
高效掌握 JeecgBoot JSelect 组件:外部传参、搜索回显与默认值设置全攻略
前端
闲适达人2 小时前
nginx传递url的获取方案
java·服务器·前端
石小石Orz2 小时前
给Claude增加状态栏显示:claude-hud保姆级教程
前端·人工智能·后端