vite:npm 安裝 pdfjs-dist , PDF.js View 示例

pdfjs-dist?是 Mozilla 的 PDF.js 庫的預構建版本,能讓你在項目里展示 PDF 文件。下面為你介紹如何用?npm?安裝?pdfjs-dist?并應用?pdf.js?和?pdf.worker.js

為了方便,我將使用?vite?搭建一個原生 js?項目。

1.創建項目
npm create vite@latest pdf-view
選:Vanilla
選:JavaScript

2.初始化項目
?cd pdf-view
?cnpm install

3.安裝 pdfjs-dist
?cnpm install pdfjs-dist@3.11.174 --save

編寫 index1.html? 如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>PDF.js View 示例</title><link rel="stylesheet" href="/pdf.css" />
</head>
<body><div class="container"><input type="file" id="fileInput" accept=".pdf"><div class="controls"><button id="prevPage">← 上一頁</button><div class="page-control"><input type="number" id="pageInput" min="1" step="1" disabled><button id="goButton" disabled>跳轉</button><span>/ <span id="totalPages">-</span></span></div><button id="nextPage">下一頁 →</button><div class="scale-control"><button id="zoomOut">-</button><span id="scaleValue">100%</span><button id="zoomIn">+</button></div></div><div id="canvasContainer"><canvas id="pdfCanvas"></canvas></div></div><script type="module" src="/pdf-view.js"></script>
</body>
</html>

?編寫 pdf.css? 如下

    .container {max-width: 1000px;margin: 10px auto;padding: 15px;}.controls {display: flex;gap: 10px;align-items: center;margin-bottom: 15px;}#canvasContainer {border: 1px solid #ddd;overflow: auto;max-height: 80vh;position: relative;}canvas {transition: transform 0.2s ease;}input[type="number"] {width: 60px;padding: 4px;text-align: center;}button {padding: 6px 12px;background: #007bff;color: white;border: none;border-radius: 4px;cursor: pointer;}button:disabled {background: #6c757d;cursor: not-allowed;}.scale-control {margin-left: auto;display: flex;align-items: center;gap: 5px;}

編寫 pdf-view.js? 如下

import * as pdfjsLib from 'pdfjs-dist';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.js';// 初始化配置
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;// 狀態管理對象
const state = {currentPage: 1,totalPages: 0,scale: 1.0,pdfDoc: null,isRendering: false,MIN_SCALE: 0.5,MAX_SCALE: 3.0,ZOOM_STEP: 0.1
};// DOM 元素引用
const dom = {canvas: document.getElementById('pdfCanvas'),container: document.getElementById('canvasContainer'),prevBtn: document.getElementById('prevPage'),nextBtn: document.getElementById('nextPage'),pageInput: document.getElementById('pageInput'),goBtn: document.getElementById('goButton'),totalPages: document.getElementById('totalPages'),zoomIn: document.getElementById('zoomIn'),zoomOut: document.getElementById('zoomOut'),scaleValue: document.getElementById('scaleValue'),fileInput: document.getElementById('fileInput')
};// 初始化事件監聽
function initEventListeners() {// 文件選擇dom.fileInput.addEventListener('change', handleFileSelect);// 翻頁控制dom.prevBtn.addEventListener('click', () => changePage(-1));dom.nextBtn.addEventListener('click', () => changePage(1));// 頁面跳轉dom.goBtn.addEventListener('click', handlePageJump);dom.pageInput.addEventListener('keypress', e => {if (e.key === 'Enter') handlePageJump();});// 縮放控制dom.zoomIn.addEventListener('click', () => changeScale(state.ZOOM_STEP));dom.zoomOut.addEventListener('click', () => changeScale(-state.ZOOM_STEP));// 鼠標滾輪縮放dom.container.addEventListener('wheel', handleWheelZoom, { passive: false });
}// 處理文件選擇
async function handleFileSelect(e) {const file = e.target.files[0];if (!file) return;try {const arrayBuffer = await file.arrayBuffer();state.pdfDoc = await pdfjsLib.getDocument(arrayBuffer).promise;state.totalPages = state.pdfDoc.numPages;initUI();await renderPage();} catch (err) {console.error('文件加載失敗:', err);}
}// 初始化界面狀態
function initUI() {dom.totalPages.textContent = state.totalPages;dom.pageInput.max = state.totalPages;dom.pageInput.value = 1;dom.pageInput.disabled = false;dom.goBtn.disabled = false;dom.zoomIn.disabled = false;dom.zoomOut.disabled = false;
}// 核心渲染函數
async function renderPage() {if (!state.pdfDoc || state.isRendering) return;state.isRendering = true;try {const page = await state.pdfDoc.getPage(state.currentPage);const viewport = page.getViewport({ scale: state.scale });// 調整畫布尺寸dom.canvas.width = viewport.width;dom.canvas.height = viewport.height;// 渲染頁面await page.render({canvasContext: dom.canvas.getContext('2d'),viewport: viewport}).promise;updateUIState();} catch (err) {console.error('頁面渲染失敗:', err);} finally {state.isRendering = false;}
}// 更新界面狀態
function updateUIState() {dom.pageInput.value = state.currentPage;dom.totalPages.textContent = state.totalPages;dom.scaleValue.textContent = `${Math.round(state.scale * 100)}%`;// 按鈕狀態dom.prevBtn.disabled = state.currentPage <= 1;dom.nextBtn.disabled = state.currentPage >= state.totalPages;dom.zoomIn.disabled = state.scale >= state.MAX_SCALE;dom.zoomOut.disabled = state.scale <= state.MIN_SCALE;
}// 翻頁處理
function changePage(offset) {const newPage = state.currentPage + offset;if (newPage < 1 || newPage > state.totalPages) return;state.currentPage = newPage;renderPage();
}// 頁面跳轉處理
function handlePageJump() {const target = parseInt(dom.pageInput.value) || 1;const validPage = Math.max(1, Math.min(target, state.totalPages));if (validPage !== state.currentPage) {state.currentPage = validPage;renderPage();}
}// 縮放處理
function changeScale(delta) {state.scale = parseFloat(Math.max(state.MIN_SCALE, Math.min(state.scale + delta, state.MAX_SCALE)).toFixed(1));renderPage();
}// 鼠標滾輪縮放處理
function handleWheelZoom(e) {if (!e.ctrlKey) return;e.preventDefault();const delta = e.deltaY > 0 ? -state.ZOOM_STEP : state.ZOOM_STEP;changeScale(delta);
}// 啟動應用
initEventListeners();

代碼解釋

  1. 導入?pdfjsLib?和?pdfjsWorker:借助 ES6 模塊語法導入?pdfjs-dist?庫和?pdf.worker.js
  2. 設置 worker 源:把?pdfjsLib.GlobalWorkerOptions.workerSrc?設為?pdfjsWorker,從而讓 PDF.js 能夠正確使用 Web Worker。
  3. 加載 PDF 文件:利用?pdfjsLib.getDocument?方法加載指定的 PDF 文件。
  4. 渲染第一頁:獲取 PDF 的第一頁,創建一個 canvas 元素,然后把頁面渲染到 canvas 上。
  5. 錯誤處理:使用?.catch?方法捕獲并處理加載 PDF 文件時可能出現的錯誤。

運行 npm run dev
? VITE v6.3.5 ?ready in 1066 ms

訪問??http://localhost:5173/index1.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82212.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82212.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82212.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

精品,架構師總結,MySQL 5.7 查詢入門詳解

文章目錄 MySQL 5.7 查詢入門詳解一、數據庫與表基礎操作1.1 連接數據庫1.2 創建數據庫1.3 使用數據庫1.4 創建數據表1.5 表結構查看 二、SELECT基礎查詢2.1 全列查詢2.2 指定列查詢2.3 別名使用2.4 去重查詢2.5 表達式計算 三、WHERE條件查詢3.1 比較運算符3.2 邏輯運算符3.3 …

P48-56 應用游戲標簽

這一段課主要是把每種道具的游戲Tag進行了整理與應用 AuraAbilitySystemComponentBase.h // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "AbilitySystemComponent.h"…

【AWS+Wordpress】將本地 WordPress 網站部署到AWS

前言 自學筆記&#xff0c;解決問題為主&#xff0c;親測有效&#xff0c;歡迎補充。 本地開發機&#xff1a;macOS&#xff08;Sequoia 15.0.1&#xff09; 服務器&#xff1a;AWS EC2&#xff08;Amazon Linux 2023&#xff09; 目標&#xff1a;從本地遷移 WordPress 到云…

從零開始:用PyTorch構建CIFAR-10圖像分類模型達到接近1的準確率

為了增強代碼可讀性&#xff0c;代碼均使用Chatgpt給每一行代碼都加入了注釋&#xff0c;方便大家在本文代碼的基礎上進行改進優化。 本文是搭建了一個稍微優化了一下的模型&#xff0c;訓練200個epoch&#xff0c;準確率達到了99.74%&#xff0c;簡單完成了一下CIFAR-10數據集…

C++復習類與對象基礎

類的成員函數為什么需要在類外定義 1.1 代碼組織與可讀性? ?類內定義?&#xff1a;適合 ?短小簡單的函數?&#xff08;如 getter/setter&#xff09;&#xff0c;能直觀體現類的接口設計。 ?類外定義?&#xff1a;當函數體較復雜時&#xff0c;將實現移到類外&#xf…

【計算機網絡】Cookie、Session、Token之間有什么區別?

大家在日常使用瀏覽器時可能會遇到&#xff1a;是否清理Cookie&#xff1f;這個問題。 那么什么是Cookie呢&#xff1f;與此相關的還有Session、Token這些。這兩個又是什么呢&#xff1f; 本文將對這三個進行講解區分&#xff0c;如果對小伙伴有幫助的話&#xff0c;也請點贊、…

Python 3.x 內置裝飾器 (4) - @dataclass

dataclass 是Python 3.7 引入的一個裝飾器&#xff0c;用來簡化創建數據類&#xff08;主要存儲數據的類&#xff09;的過程。它會自動為類生成一些常用的方法&#xff0c;比如&#xff1a; __init__: 對象的初始化 __repr__: 定義類的官方字符串表示。 __eq__: 定義兩個對象…

第一次被AI指點出文章的問題

二十年&#xff0c;幾乎從未收到過這種程度的反饋。大部分意見都是有效的批評。 1.前言 關于鏈家左暉的一篇評論稿 這篇文章有什么問題嗎&#xff1f;所有方面都可以談&#xff0c;包括敘述&#xff0c;用詞&#xff0c;重復&#xff0c;真實性&#xff0c;偏見&#xff0c;…

var、let、const三者之間的區別和使用

var、let、const 都是用于聲明變量的關鍵字&#xff0c;可以通過作用域、可變性、變量提升幾個方面進行區分&#xff1b; 1&#xff0c;作用域 1&#xff09;var的屬于函數作用域&#xff0c;只能在函數內使用。若在函數外部聲明變量&#xff0c;會變為全局變量&#xff1b; …

Consumer Group的作用是什么?Rebalance的觸發條件有哪些? (實現消費者負載均衡;消費者加入/離開、訂閱Topic變化等)

好的&#xff0c;我現在需要回答用戶關于Kafka Consumer Group和Rebalance的問題。首先&#xff0c;用戶問的是Consumer Group的作用以及Rebalance的觸發條件。根據之前的對話歷史&#xff0c;用戶已經了解了Kafka的基本組件、消息保留策略、順序性保證等&#xff0c;現在的問題…

出一期Source Insigned的使用教程

1. 創建新項目 打開 Source Insight&#xff0c;點擊菜單欄的 Project > New Project。在彈出的窗口中&#xff0c;輸入項目名稱&#xff08;建議與項目內容相關&#xff0c;便于識別&#xff09;。指定項目數據文件的存儲路徑&#xff08;即 Source Insight 配置文件保存的…

A. Row GCD(gcd的基本性質)

Problem - 1458A - Codeforces 思路&#xff1a; 首先得知道gcd的兩個基本性質&#xff1a; (1) gcd(a,b)gcd(a,|b-a|) (2) gcd(a,b,c)gcd(a,gcd(b,c)) 結合題目所給的a1bj&#xff0c;a2bj...... anbj 根據第一條性質得到&#xff1a; gcd(a1bj&#xff0c;a2bj)gcd(…

ES6入門---第三單元 模塊三:async、await

async function fn(){ //表示異步&#xff1a;這個函數里面有異步任務 let result await xxx //表示后面結果需要等待 } 讀取文件里數據實例&#xff1a; const fs require(fs);//簡單封裝 fs封裝成一個promise const readFile function (fileName){return…

如何在 C# 和 .NET 中打印 DataGrid

DataGrid 是 .NET 架構中一個功能極其豐富的組件&#xff0c;或許也是最復雜的組件之一。寫這篇文章是為了回答“我到底該如何打印 DataGrid 及其內容”這個問題。最初即興的建議是使用我的屏幕截圖文章來截取表單&#xff0c;但這當然無法解決打印 DataGrid 中虛擬顯示的無數行…

C語言 指針(5)

目錄 1.冒泡排序 2.二級指針 3.指針數組 4.指針數組模擬二級數組 1.冒泡排序 1.1 基本概念 冒泡排序&#xff08;Bubble Sort&#xff09; 是一種簡單的排序算法&#xff0c;它重復地遍歷要排序的數列&#xff0c;一次比較兩個元 素&#xff0c;如果它們的順序錯誤就把它…

15前端項目----用戶信息/導航守衛

登錄/注冊 持久存儲用戶信息問題 退出登錄導航守衛解決問題 持久存儲用戶信息 本地存儲&#xff1a;&#xff08;在actions中請求成功時&#xff09; 添加localStorage.setItem(token,result.data.token);獲取存儲&#xff1a;&#xff08;在user倉庫中&#xff0c;state中tok…

RSS 2025|斯坦福提出「統一視頻行動模型UVA」:實現機器人高精度動作推理

導讀 在機器人領域&#xff0c;讓機器人像人類一樣理解視覺信息并做出精準行動&#xff0c;一直是科研人員努力的方向。今天&#xff0c;我們要探討的統一視頻行動模型&#xff08;Unified Video Action Model&#xff0c;UVA&#xff09;&#xff0c;就像給機器人裝上了一個“…

基于論文的大模型應用:基于SmartETL的arXiv論文數據接入與預處理(四)

上一篇介紹了基于SmartETL框架實現arxiv采集處理的基本流程&#xff0c;通過少量的組件定制開發&#xff0c;配合yaml流程配置&#xff0c;實現了復雜的arxiv采集處理。 由于其業務流程復雜&#xff0c;在實際應用中還存在一些不足需要優化。 5. 基于Kafka的任務解耦設計 5.…

Fiori學習專題三十五:Device Adaptation

由于在類似于手機的小面板上顯示時&#xff0c;我們為了留出更多空間展示數據&#xff0c;可以將一些控件折疊。 1.修改HelloPanel.view.xml&#xff0c;加入expandable“{device>/system/phone}” expanded"{ !${device>/system/phone} <mvc:ViewcontrollerNam…

【記錄】HunyuanVideo 文生視頻工作流

HunyuanVideo 文生視頻工作流指南 概述 本指南詳細介紹如何在ComfyUI中使用騰訊混元HunyuanVideo模型進行文本到視頻生成的全流程操作&#xff0c;包含環境配置、模型安裝和工作流使用說明。 參考&#xff1a;https://comfyui-wiki.com/zh/install/install-comfyui/install-c…