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.pswp.cn/news/904753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904753.shtml
英文地址,請注明出處:http://en.pswp.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神經網絡線…