好的,我给你整理一份 前端实现 PDF 文件预览的完整操作步骤方法(2025 最新版),包含浏览器原生方法、PDF.js 实现、文件上传动态预览,以及分页和缩放功能。
🚀 前端实现 PDF 文件预览步骤
一、使用浏览器原生方法(快速实现)
1️⃣ <iframe> 标签
<iframe src="example.pdf" width="100%" height="600px"></iframe>
2️⃣ <embed> 标签
<embed src="example.pdf" type="application/pdf" width="100%" height="600px" />
✅ 优点:简单,无需第三方库
⚠️ 缺点:移动端兼容性差,功能有限(无法分页、缩放、跳页控制)
二、使用 PDF.js 渲染 PDF(推荐)
PDF.js 是 Mozilla 官方开源库,可在前端渲染 PDF。
1️⃣ 安装 PDF.js
npm install pdfjs-dist
2️⃣ 基础渲染示例
<canvas id="pdfCanvas"></canvas>
<script type="module">
import * as pdfjsLib from "pdfjs-dist/build/pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
const url = 'example.pdf';
const canvas = document.getElementById('pdfCanvas');
const ctx = canvas.getContext('2d');
async function renderPDF(url, pageNumber = 1) {
const pdf = await pdfjsLib.getDocument(url).promise;
const page = await pdf.getPage(pageNumber);
const viewport = page.getViewport({ scale: 1.5 });
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: ctx, viewport }).promise;
}
renderPDF(url);
</script>
三、用户上传 PDF 动态预览
<input type="file" id="fileInput" accept="application/pdf" />
<canvas id="pdfCanvas"></canvas>
<script type="module">
import * as pdfjsLib from "pdfjs-dist/build/pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
const input = document.getElementById("fileInput");
const canvas = document.getElementById("pdfCanvas");
const ctx = canvas.getContext("2d");
input.addEventListener("change", async (e) => {
const file = e.target.files[0];
if (!file) return;
const fileURL = URL.createObjectURL(file);
const pdf = await pdfjsLib.getDocument(fileURL).promise;
const page = await pdf.getPage(1);
const viewport = page.getViewport({ scale: 1.5 });
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: ctx, viewport }).promise;
});
</script>
✅ 特点:支持用户上传文件,动态预览
四、增强功能(分页、缩放、旋转)
- 分页浏览
let currentPage = 1;
async function nextPage(pdf) {
if(currentPage < pdf.numPages) currentPage++;
const page = await pdf.getPage(currentPage);
const viewport = page.getViewport({ scale: 1.5 });
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: ctx, viewport }).promise;
}
- 缩放
const viewport = page.getViewport({ scale: 2.0 }); // 缩放倍数
- 旋转
const viewport = page.getViewport({ scale: 1.5, rotation: 90 });
- 远程 PDF + 鉴权
const res = await fetch(url, { headers: { Authorization: "Bearer token" } });
const blob = await res.blob();
const pdf = await pdfjsLib.getDocument(URL.createObjectURL(blob)).promise;
五、使用组件库封装(Vue / React / Angular)
| 框架 | 推荐库 | 特点 |
|---|---|---|
| Vue3 | vue-pdf | 封装 PDF.js,支持分页、缩放 |
| React | react-pdf | React 组件化,功能全面 |
| Angular | ngx-extended-pdf-viewer | 强大功能,支持缩放、搜索、注释 |
Vue3 示例
<template>
<pdf src="example.pdf"></pdf>
</template>
<script setup>
import pdf from 'vue-pdf';
</script>
六、操作步骤总结
- 快速预览:使用
<iframe>或<embed> - 高自定义:使用 PDF.js 渲染到
<canvas> - 用户上传文件:用 Blob + PDF.js
- 增强体验:分页、缩放、旋转、搜索
- 框架项目:使用
vue-pdf/react-pdf/ngx-extended-pdf-viewer封装
好,我帮你整理一份 Vue3 + PDF.js 全功能 PDF 预览示例项目,包含分页、缩放、用户上传文件和远程 PDF 渲染,一键可运行。
📦 Vue3 + PDF.js PDF 预览示例项目
1️⃣ 安装依赖
npm init vue@latest pdf-preview-demo
cd pdf-preview-demo
npm install
npm install pdfjs-dist
2️⃣ 项目结构(示例)
src/
├─ components/
│ └─ PdfViewer.vue
├─ App.vue
└─ main.js
3️⃣ PdfViewer.vue
<template>
<div>
<input type="file" @change="onFileChange" accept="application/pdf" />
<div class="controls">
<button @click="prevPage">上一页</button>
<span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
<button @click="nextPage">下一页</button>
<button @click="zoomIn">放大</button>
<button @click="zoomOut">缩小</button>
</div>
<canvas ref="pdfCanvas"></canvas>
</div>
</template>
<script setup>
import { ref } from "vue";
import * as pdfjsLib from "pdfjs-dist/build/pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
const pdfCanvas = ref(null);
const currentPage = ref(1);
const totalPages = ref(0);
let pdfDoc = null;
let scale = 1.5;
const renderPage = async (pageNum) => {
const page = await pdfDoc.getPage(pageNum);
const viewport = page.getViewport({ scale });
const canvas = pdfCanvas.value;
const ctx = canvas.getContext("2d");
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: ctx, viewport }).promise;
};
const loadPDF = async (url) => {
pdfDoc = await pdfjsLib.getDocument(url).promise;
totalPages.value = pdfDoc.numPages;
currentPage.value = 1;
renderPage(currentPage.value);
};
const onFileChange = async (event) => {
const file = event.target.files[0];
if (!file) return;
const fileURL = URL.createObjectURL(file);
await loadPDF(fileURL);
};
const nextPage = () => {
if (currentPage.value < totalPages.value) {
currentPage.value++;
renderPage(currentPage.value);
}
};
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
renderPage(currentPage.value);
}
};
const zoomIn = () => {
scale += 0.25;
renderPage(currentPage.value);
};
const zoomOut = () => {
if (scale > 0.5) {
scale -= 0.25;
renderPage(currentPage.value);
}
};
// 示例加载远程 PDF
// loadPDF('https://example.com/sample.pdf');
</script>
<style scoped>
.controls {
margin: 10px 0;
display: flex;
align-items: center;
gap: 10px;
}
canvas {
border: 1px solid #ccc;
}
</style>
4️⃣ App.vue
<template>
<div id="app">
<h1>Vue3 PDF 预览 Demo</h1>
<PdfViewer />
</div>
</template>
<script setup>
import PdfViewer from './components/PdfViewer.vue'
</script>
<style>
#app {
padding: 20px;
}
</style>
5️⃣ main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
6️⃣ 功能说明
- 用户上传 PDF 文件 → 立即预览
- 分页控制 → 上一页 / 下一页
- 缩放 → 放大 / 缩小
- 远程 PDF 渲染 → 可通过
loadPDF(url)加载 - 完全基于 PDF.js → 无依赖 iframe
发表回复