当前位置: 首页 > news >正文

vue2利用canvas翻页浏览pdf文件

 利用iframe纵向浏览文件

一、下载pdf.js包

链接:https://github.com/mozilla/pdf.js/tags

里面有很多的版本, 高版本的可能浏览器不兼容或者不兼容vue2,有时还要考虑移动端,最好下载低版本的,这里是v2.16.105-dist版本(选择带 dist 的压缩包,包含预编译文件)。)

二、引入vue2项目中

在本地static里面创建文件夹pdfjs,然后将下载包里面的文件放进pdfjs。

pdf.js包的目录结构,有的不一样,没关系,放进static里面就好

三、pdf浏览组件

<template><div class="pdf-viewer"><!-- 工具栏 --><div class="pdf-toolbar"><div class="page-controls"><button @click="prevPage" :disabled="currentPage <= 1"><i class="el-icon-arrow-left"></i></button><span><input type="number" v-model.number="pageInput" @change="goToPage" :min="1" :max="totalPages"class="page-input" /><!-- / 共 {{ totalPages }} 页 --></span><button @click="nextPage" :disabled="currentPage >= totalPages"><i class="el-icon-arrow-right"></i></button></div><div class="openBox"><button @click="zoomOut" :disabled="scale <= 0.5"><i class="el-icon-zoom-out"></i></button><span class="scale-info">{{ (scale * 100).toFixed(0) }}%</span><button @click="zoomIn" :disabled="scale >= 3"><i class="el-icon-zoom-in"></i></button></div></div><!-- PDF 内容区域 --><div class="pdf-content"><div class="loading" v-if="loading"><div class="spinner"></div><p>加载中...</p></div><div class="error" v-if="error">{{ error }}</div><div class="canvasstyle" v-else><canvas id="pdfCanvas"></canvas><!-- <iframe  id="myIframe" :src="iframeSrc" width="100%" height="100%"></iframe> --></div></div></div>
</template><script>
export default {name: "PdfViewer",props: {// PDF 文件地址(本地路径或远程 URL)pdfUrl: {type: String,required: true,},},data() {return {pdfjsLib: null, // pdfjs 库实例pdfDoc: null, // PDF 文档实例currentPage: 1, // 当前页码totalPages: 0, // 总页数scale: 0.7, // 缩放比例pageInput: 1, // 页码输入框loading: true, // 加载状态error: "", // 错误信息iframeSrc: '../../../static/pdfjs-2.16.105-dist/web/viewer.html?file=' + '../../../static/pdf/1001.pdf#page=10', // 用于存储 iframe 的 src 属性};},watch: {currentPage(newVal) {this.pageInput = newVal;},scale() {this.renderPage(this.currentPage);},},mounted() {// 动态引入 pdf.min.jsthis.loadPdfJsLibrary();},methods: {// 加载 pdfjs 库loadPdfJsLibrary() {// 也可以直接下载html里面,是一个道理const script = document.createElement("script");// 路径对应 public/static/pdfjs/build/pdf.min.jsscript.src = "../../../static/pdfjs-2.16.105-dist/build/pdf.js";script.onload = () => {// 库加载完成后获取全局实例this.pdfjsLib = window.pdfjsLib;// 配置 worker 路径this.pdfjsLib.GlobalWorkerOptions.workerSrc ="../../../static/pdfjs-2.16.105-dist/build/pdf.worker.js";// 加载 PDF 文档this.loadPdfDocument();};script.onerror = () => {this.error = "PDF 库加载失败,请检查文件路径";this.loading = false;};document.head.appendChild(script);},// 加载 PDF 文档async loadPdfDocument() {try {this.loading = true;// 加载 PDF(支持本地路径或远程 URL)this.pdfDoc = await this.pdfjsLib.getDocument(this.pdfUrl).promise;this.totalPages = this.pdfDoc.numPages;this.renderPage(1); // 渲染第一页} catch (err) {this.error = `PDF 加载失败: ${err.message}`;console.error("加载错误:", err);} finally {this.loading = false;}},// 渲染指定页码async renderPage(pageNum) {if (!this.pdfDoc) return;try {this.loading = true;const page = await this.pdfDoc.getPage(pageNum);// 根据缩放比例计算视图大小const viewport = page.getViewport({ scale: this.scale });// 设置 canvas 尺寸并渲染const canvas = document.getElementById("pdfCanvas");const ctx = canvas.getContext("2d");canvas.width = viewport.width;canvas.height = viewport.height;await page.render({canvasContext: ctx,viewport: viewport,}).promise;this.currentPage = pageNum;} catch (err) {this.error = `页面渲染失败: ${err.message}`;console.error("渲染错误:", err);} finally {this.loading = false;}},// 上一页prevPage() {if (this.currentPage > 1) {this.renderPage(this.currentPage - 1);}},// 下一页nextPage() {if (this.currentPage < this.totalPages) {this.renderPage(this.currentPage + 1);}},// 跳转到指定页goToPage() {let page = Math.floor(this.pageInput);// 边界校验if (page < 1) page = 1;if (page > this.totalPages) page = this.totalPages;if (page !== this.currentPage) {this.renderPage(page);}},// 放大zoomIn() {this.scale += 0.1;},// 缩小zoomOut() {this.scale -= 0.1;},},
};
</script><style scoped>
.pdf-viewer {max-width: 100%;margin: 0 auto;
}.pdf-toolbar {display: flex;align-items: center;justify-content: space-between;padding: 10px 2px;
}.openBox {display: flex;align-items: center;
}.pdf-toolbar button {padding: 4px 6px;border: none;background-color: #ffffff;border: 1px solid #e5e5e5;/* color: white; */border-radius: 4px;/* cursor: pointer; *//* transition: background-color 0.2s; */
}.pdf-toolbar button:disabled {background-color: #cccccc93;cursor: not-allowed;
}
.scale-info {margin: 0 10px;min-width: 50px;text-align: center;
}.page-controls {display: flex;align-items: center;
}.page-input {width: 50px;padding: 5px;margin: 0 4px;text-align: center;border: 1px solid #e5e5e5;
}.jump {margin-left: 4px;
}.pdf-content {width: 100%;text-align: center;border: 1px solid #e0e0e0;border-radius: 8px;background-color: #ffffff;display: flex;flex-direction: column;justify-content: center;min-height: 300px;
}.canvasstyle {width: 100%;overflow: auto;text-align: center;
}.canvasstyle::-webkit-scrollbar {display: none;/* Chrome Safari */
}.loading {width: 100%;text-align: center;padding: 50px 0;
}.spinner {width: 40px;height: 40px;margin: 0 auto;border: 4px solid #f3f3f3;border-top: 4px solid #4285f4;border-radius: 50%;animation: spin 1s linear infinite;
}@keyframes spin {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}
}.error {color: #dc3545;text-align: center;padding: 50px 0;
}
</style>

四、父组件使用

直接引入传值就行

<PdfViewer   :pdfUrl="pdfUrl" />

http://www.dtcms.com/a/395525.html

相关文章:

  • 仿生视觉芯片迈向实用化:《Advanced Science》报道双极性宽谱光电晶体管,赋能自动驾驶与机器感知
  • 如何在手机上把CAD图纸导出为PDF?
  • 【2025最新】02 Spring Boot 第一个小程序 for VS Code - 通过 Spring Initializr 扩展创建
  • map和set的使用和实现(C++)
  • Qt 系统相关 - 网络
  • Java中List转换成Map的两种方式
  • 嵌入式 - RAM10
  • Qwen新开源tongyi-DeepResearch:核心优势
  • Java Stream API性能优化实践指南
  • Qt配置序列化与反序列化实战:QSettings的深度应用指南
  • MySQL下载时出现“starting the server”或“initializing错误”的原因以及解决方案
  • MySQL 数据库核心知识点详解
  • 让机器人边思考边行动!新一代具身智能EO-1:统一架构突破VLA瓶颈
  • 数据库笔试选择题:题组1
  • 一款相机是只有桶形畸变 和 枕形畸变的一种,还是两个都有?
  • 德克西尔井盖异动传感器:城市安全的隐形守护者
  • HTML基本标签一
  • BGP高防服务器具体是指什么
  • 打工人日报#20250922
  • Django视图与路由
  • 在thinkphp8的模板文件中 如何调用公共服务类函数
  • Nextcloud增加模块内嵌网页
  • Ubuntu18.04 MySQL5.7.42 内存升高导致OOM MySQL重启解决办法
  • html调起exe程序
  • C#中的Task怎么理解,理解异步编程的核心
  • fastApi框架开发一个web端仓库管理系统
  • mosquitto求医之路(3):Docker安装也不好使
  • 字节 TRAE:AI 原生 Coding Agent 的工程化架构与实战落地
  • 保姆级教程:windows和linux双系统的电脑如何无副作用,安全删除linux
  • SSM宠物领养平台16e63(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。