vue3: pdf.js5.2.133 using typescript

npm install pdfjs-dist@5.2.133

项目结构:

<!--* @creater: geovindu* @since: 2025-05-09 21:56:20* @LastAuthor: geovindu* @lastTime: 2025-05-09 22:12:17* @文件相对于项目的路径: \jsstudy\vuepdfpreview\comonents\pdfjs.vue* @message: geovindu* @IDE: vscode* @Development: node.js 20, vuejs3.0* @package:* @ISO: windows10* @database: mysql 8.0 sql server 2019 postgresSQL 16* Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved.
-->
<template><div class="pdf-container"><div v-if="loading" class="text-center py-8">加载中...</div><div v-else-if="error" class="text-center py-8 text-red-500">{{ error }}</div><div v-else><!-- 控制工具栏 --><div class="flex justify-between items-center mb-4"><div class="flex space-x-2"><button @click="zoomIn" class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"><i class="fa fa-search-plus mr-1"></i> 放大</button><button @click="zoomOut" class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"><i class="fa fa-search-minus mr-1"></i> 缩小</button><button @click="downloadPDF" class="px-3 py-1 bg-green-500 text-white rounded hover:bg-green-600"><i class="fa fa-download mr-1"></i> 下载文档</button></div><div class="text-center">缩放比例: {{ Math.round(scale * 100) }}%</div></div><!-- PDF 容器 --><div id="pdf-container" class="w-full h-[600px] border border-gray-300 overflow-auto"><canvas ref="pdfCanvas"></canvas></div><!-- 页码控制 --><div class="mt-4 text-center"><button @click="firstPage" :disabled="currentPage <= 1" class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300 mx-1">第一页</button><button @click="prevPage" :disabled="currentPage <= 1" class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300 mx-1">上一页</button><span class="mx-3">第 {{ currentPage }} / {{ totalPages }} 页</span><button @click="nextPage" :disabled="currentPage >= totalPages" class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300 mx-1">下一页</button><button @click="lastPage" :disabled="currentPage >= totalPages" class="px-3 py-1 bg-gray-200 rounded hover:bg-gray-300 mx-1">最后一页</button></div></div></div></template><script setup>import { ref, onMounted, reactive } from 'vue';import * as pdfjsLib from 'pdfjs-dist';// 设置 worker 路径//pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs/pdf.worker.mjs';// 动态解析worker路径,确保使用.mjs文件
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.mjs',import.meta.url
).toString();const props = defineProps({pdfUrl: { type: String, required: true }});const pdfCanvas = ref(null);const loading = ref(true);const error = ref('');const currentPage = ref(1);const totalPages = ref(0);const scale = ref(1.0);let pdfDoc = null;const renderPage = async (num) => {try {const page = await pdfDoc.getPage(num);const viewport = page.getViewport({ scale: scale.value });// 设置 canvas 尺寸pdfCanvas.value.width = viewport.width;pdfCanvas.value.height = viewport.height;// 渲染页面const renderContext = {canvasContext: pdfCanvas.value.getContext('2d'),viewport: viewport};await page.render(renderContext).promise;currentPage.value = num;} catch (err) {console.error('渲染页面失败:', err);error.value = `渲染失败: ${err.message}`;}};const prevPage = () => {if (currentPage.value > 1) {renderPage(currentPage.value - 1);}};const nextPage = () => {if (currentPage.value < totalPages.value) {renderPage(currentPage.value + 1);}};const firstPage = () => {if (currentPage.value !== 1) {renderPage(1);}};const lastPage = () => {if (currentPage.value !== totalPages.value) {renderPage(totalPages.value);}};const zoomIn = () => {scale.value = Math.min(scale.value + 0.1, 3.0); // 最大缩放 300%renderPage(currentPage.value);};const zoomOut = () => {scale.value = Math.max(scale.value - 0.1, 0.5); // 最小缩放 50%renderPage(currentPage.value);};const downloadPDF = () => {try {const link = document.createElement('a');link.href = props.pdfUrl;link.download = props.pdfUrl.split('/').pop() || 'document.pdf';link.click();} catch (e) {console.error('下载失败:', e);error.value = '下载失败,请尝试右键另存为';window.open(props.pdfUrl, '_blank');}};onMounted(async () => {try {// 加载 PDFconst loadingTask = pdfjsLib.getDocument(props.pdfUrl);pdfDoc = await loadingTask.promise;totalPages.value = pdfDoc.numPages;// 渲染第一页renderPage(1);loading.value = false;} catch (err) {console.error('加载 PDF 失败:', err);error.value = `加载失败: ${err.message}`;loading.value = false;}});</script><style scoped>.pdf-container {max-width: 1000px;margin: 0 auto;}#pdf-container canvas {max-width: 100%;display: block;margin: 0 auto;}</style>
<!--* @creater: geovindu* @since: 2025-05-09 21:56:20* @LastAuthor: geovindu* @lastTime: 2025-05-09 22:12:17* @文件相对于项目的路径: \jsstudy\vuepdfpreview\src\App.vue* @message: geovindu* @IDE: vscode* @Development: node.js 20, vuejs3.0* @package:* @ISO: windows10* @database: mysql 8.0 sql server 2019 postgresSQL 16* Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved.
--><template>
<div class="pdf-container"><PDFView :pdfUrl="pdfUrl" v-if="pdfUrl" /><div v-else >加载中...</div>
</div><div><a href="https://vite.dev" target="_blank"><img src="/vite.svg" class="logo" alt="Vite logo" /></a><a href="https://vuejs.org/" target="_blank"><img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /></a></div><HelloWorld msg="Vite + Vue" />
</template>
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
//import PDFView from './components/vuepdfjs.vue' // 可以//import PDFView from './components/pdfPreview.vue' // 可以import PDFView from "./components/pdfjs.vue"   //可以//import pdfUrl from "./pdfs/01.pdf"const pdfUrl = "./pdfs/09.pdf"</script>
<style scoped>
.logo {height: 6em;padding: 1.5em;will-change: filter;transition: filter 300ms;
}
.logo:hover {filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

H2Database SQL 插入流程

H2Database SQL 插入流程 插入数据时会先进行 SQL 解析,然后找到插入表对应的 Primary Index 对应的 BTree,然后根据二分法定位到插入的叶子节点,将 key(主键) 和 value(Row) 插入到指定的叶子节点. 解析 SQL session 加锁 创建 savepoint获取or创建事务 设置 savepoint 执行…

虚拟机ubantu20.04系统桥接模式下无法ping通外网,但可以ping通本机的解决方案

1.出现的问题&#xff1a; 虚拟机ubantu20.04系统桥接模式下无法ping通外网,但可以ping通本机。 2.解决方案&#xff1a; 如果 DHCP 未分配 IP 地址&#xff0c;可以手动配置静态 IP&#xff1a; 1.编辑网络配置文件&#xff1a; sudo nano /etc/netplan/01-netcfg.yaml 修…

面对渠道竞争,品牌该如何应对?

无论是传统零售渠道还是电商平台的&#xff0c;渠道竞争仍旧是品牌维持和扩大影响力绕不开的一环。品牌想要保证自身的市场地位和盈利能力&#xff0c;就需要充分发挥各方面的优势&#xff0c;来应对多变的市场环境。 一、改变产品定位 在存量市场上&#xff0c;消费者本身拥有…

SpringAI特性

一、SpringAI 顾问&#xff08;Advisors&#xff09; Spring AI 使用 Advisors机制来增强 AI 的能力&#xff0c;可以理解为一系列可插拔的拦截器&#xff0c;在调用 AI 前和调用 AI 后可以执行一些额外的操作&#xff0c;比如&#xff1a; 前置增强&#xff1a;调用 AI 前改…

101alpha_第6个

第6个alpha (-1 * correlation(open, volume, 10)) 这个就是看这两个相似性。10天之内的 如果结果为正且数值较大&#xff0c;投资者可能会认为在开盘价上涨时成交量萎缩&#xff0c;市场上涨动力不足&#xff0c;可能是卖出信号&#xff1b;反之&#xff0c;开盘价下跌时成交…

【渗透测试】Web服务程序解析漏洞原理、利用方式、防范措施

文章目录 Web服务程序解析漏洞原理、利用方式、防范措施一、原理**1. 定义与触发条件****2. 攻击链流程图** 二、利用方式**1. 常见漏洞类型与利用手法**(1) IIS 5.x-6.x解析漏洞(2) Apache解析漏洞(3) Nginx解析漏洞(4) IIS 7.x解析漏洞(5) PHP CGI解析漏洞&#xff08;CVE-20…

SSL证书格式详解:PEM、CER、DER、JKS、PKCS12等

引言 在网络安全领域&#xff0c;SSL/TLS证书是保障互联网通信安全的核心工具。它们通过加密连接&#xff0c;确保服务器与客户端之间的数据隐私和完整性。然而&#xff0c;对于初学者来说&#xff0c;SSL证书的多种格式——PEM、CER、JKS、PKCS12、PFX等——常常令人困惑。每…

生信服务器如何安装cellranger|生信服务器安装软件|单细胞测序软件安装

一.Why cellranger Cell Ranger 是由 10x Genomics 公司开发的一款用于处理其单细胞测序&#xff08;single-cell RNA-seq, scRNA-seq&#xff09;数据的软件套件。它主要用于将原始测序数据&#xff08;fastq 文件&#xff09;转换为可以用于下游分析的格式&#xff0c;比如基…

Redis 常见数据类型

Redis 常见数据类型 一、基本全局命令详解与实操 1. KEYS 命令 功能&#xff1a;按模式匹配返回所有符合条件的键&#xff08;生产环境慎用&#xff0c;可能导致阻塞&#xff09;。 语法&#xff1a; KEYS pattern 模式规则&#xff1a; h?llo&#xff1a;匹配 hello, ha…

33号远征队 - 游玩鉴赏

风景很好画质很好 , 图片太大只能截图一小部分 地编和特效 值得参考

使用JMETER中的JSON提取器实现接口关联

一、JSON提取器介绍 JSON提取器是JMETER工具中用于从JSON响应中提取数据的重要组件&#xff0c;常常用于接口关联场景中&#xff08;参数传递&#xff09;。 二、添加JSON提取器 举例&#xff08;积分支付接口请求数据依赖于创建订单接口响应的payOrderId&#xff09; 1.在…

QT6(35)4.8定时器QTimer 与QElapsedTimer:理论,例题的界面搭建,与功能的代码实现。

&#xff08;112&#xff09; &#xff08;113&#xff09;模仿随书老师给的源代码搭建的&#xff0c; LCD 显示的部分不一样 &#xff1a; &#xff08;114&#xff09;以下开始代码完善&#xff1a; 关联定时器的信号与槽函数 &#xff1a; &#xff08;115&#xff09;…

nvidia-smi 和 nvcc -V 作用分别是什么?

命令1&#xff1a;nvidia-smi 可以查看当前显卡的驱动版本&#xff0c;以及该驱动支持的CUDA版本。 命令2&#xff1a;nvcc -V 可以看到实际安装的CUDA工具包版本为 12.8 更详细的介绍&#xff0c;可以参考如下链接

Excel 数据 可视化 + 自动化!Excel 对比软件

各位Excel小能手们&#xff01;你们有没有过要对比两个Excel表格数据差异&#xff0c;却看得眼睛都花了的经历&#xff1f;其实啊&#xff0c;现在有专门的Excel文件比较软件能帮咱解决这大难题。这软件就是用来快速找出两个或多个Excel表格数据不同之处&#xff0c;还能把修改…

《软件项目经济性论证报告模板:全面解析与策略建议》

《软件项目经济性论证报告模板:全面解析与策略建议》 一、引言 1.1 项目背景阐述 在数字化浪潮席卷全球的当下,各行业对软件的依赖程度日益加深。[行业名称] 行业也不例外,随着业务规模的不断扩张、业务复杂度的持续提升以及市场竞争的愈发激烈,对高效、智能、定制化软件…

高频工业RFID读写器-三格电子

高频工业RFID读写器 型号&#xff1a;SG-HF40-485、SG-HF40-TCP 产品功能 高频工业读写器&#xff08;RFID&#xff09;产品用在自动化生产线,自动化分拣系统,零部件组装产线等情境下&#xff0c;在自动化节点的工位上部署RFID读写设备&#xff0c;通过与制品的交互&#xf…

2025年5月计划(linux+Gpu精粹催眠+UE独立游戏)

终于步入正轨了&#xff0c;4月份为了各种面试&#xff0c;一会学这&#xff0c;一会学那。 现在&#xff0c;有大量的业余时间了&#xff0c;也该干点正事了。 按照规划&#xff0c; 1&#xff0c;ue独立游戏&#xff08;十分钟的视频即可&#xff09; 2&#xff0c;linux-&…

计算机学习路线与编程语言选择(信息差)

——授人以鱼不如授人以渔 计算机学习公式&#xff1a;1/3科班思维 1/3路线选择 1/3工程能力 好工作随便找&#xff08;来自B站小毛毛熊&#xff09; 本文主要是路线选择&#xff01;&#xff01;&#xff01;下面开始吧。 面向岗位学习&#xff01;到招聘网站看看有哪些…

『Python学习笔记』ubuntu解决matplotlit中文乱码的问题!

ubuntu解决matplotlit中文乱码的问题&#xff01; 文章目录 simhei.ttf字体下载链接&#xff1a;http://xiazaiziti.com/210356.html将字体放到合适的地方 sudo cp SimHei.ttf /usr/share/fonts/(base) zkfzkf:~$ fc-list | grep -i "SimHei" /usr/local/share/font…

电动汽车充换电设施可调能力聚合评估与预测 - 使用说明文档

电动汽车充换电设施可调能力聚合评估与预测 - 使用说明文档 概述 本脚本real_data_model.m基于论文《大规模电动汽车充换电设施可调能力聚合评估与预测》(鲍志远&#xff0c;胡泽春)实现了电动汽车充电设施的负荷预测和可调能力评估。使用混合模型&#xff08;LSTM神经网络线…