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.mzph.cn/news/904693.shtml

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

相关文章

【Android】动画原理解析

一,基础动画 基础动画,有四种,分别是平移(Translate)、缩放(Scale)、Rorate(旋转)、Alpha(透明度),对应Android中以下四种。 1,Animation基类 1,基本概念 1,插值器 插值器的作用,是控制动画过程的参数,可以理解为 时间(t)与动画进程(d)的函数,动画仅…

手撕基于AMQP协议的简易消息队列-2(所用第三方库的介绍与简单使用)

第三方库的介绍 Protobuf 什么是Protobuf&#xff08;Protocol Buffer&#xff09;&#xff1f; Protobuf是数据结构序列化和反序列化框架 Protobuf的特点有哪些&#xff1f; 通用性&#xff1a;语⾔⽆关、平台⽆关。即 ProtoBuf ⽀持 Java、C、Python 等多种语⾔&#xf…

Altera系列FPGA实现图像视频采集转HDMI/LCD输出,提供4套Quartus工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目Altera系列FPGA相关方案推荐 3、设计思路框架工程设计原理框图输入Sensor之-->OV7725摄像头输入Sensor之-->OV5640摄像头输入Sensor之-->串口传图输入图像缓…

ABP vNext 集成 CAP + RabbitMQ 实现可靠事件总线

&#x1f680; ABP vNext 集成 CAP RabbitMQ 实现可靠事件总线 在分布式系统中&#xff0c;事件总线是实现服务解耦与最终一致性的核心手段。本文将以 ABP vNext 8.1 为基础&#xff0c;手把手教你如何集成 CAP RabbitMQ 构建可靠的事件驱动架构。 &#x1f3af; 本文适用于…

Linux 服务器静态 IP 配置初始化指南

✅ 第一步&#xff1a;确认网络管理方式 运行以下命令判断系统使用的网络管理服务&#xff1a; # 检查 NetworkManager 是否活跃 systemctl is-active NetworkManager# 检查 network&#xff08;旧服务&#xff09;是否活跃 systemctl is-active network或者检查配置路径&…

C++ 工具链与开发实践:构建安全、高效与创新的开发生态

引言 在 C 的技术演进中&#xff0c;工具链的革新与开发实践的迭代始终是推动语言生命力的核心动力。从内存安全的攻防体系到嵌入式设备的能效优化&#xff0c;从跨平台开发的降本增效到开发者社区的生态构建&#xff0c;C 正通过工具链与方法论的双重升级&#xff0c;应对复杂…

跨浏览器自动化测试的智能生成方法

一、背景与挑战&#xff1a;跨浏览器测试为什么“难”&#xff1f; 在现代Web应用开发中&#xff0c;跨浏览器兼容性是用户体验的底线保障。面对Chrome、Firefox、Safari、Edge乃至IE、移动浏览器等多种运行环境&#xff0c;开发者与测试人员常面临&#xff1a; 相同DOM在不同…

【Hive入门】Hive安全管理与权限控制:用户认证与权限管理深度解析

目录 引言 1 Hive安全管理体系概述 2 Hive用户认证机制 2.1 Kerberos集成认证 2.1.1 Kerberos基本原理 2.1.2 Hive集成Kerberos配置步骤 2.1.3 Kerberos认证常见问题排查 2.2 LDAP用户同步 2.2.1 LDAP协议概述 2.2.2 Hive集成LDAP配置 2.2.3 LDAP与Hive用户同步架构…

0X. Linux嵌入式系统(课堂笔记)

目录 一. 开发板桥接 二. 开发板白屏 三. 0324-MPU6050开发 3.1 函数详解 3.2 常用 ioctl 请求码&#xff08;request&#xff09; 3.3 头文件详解 四. 获取鼠标信息 4.1 获取鼠标信息 4.2 内核修改并编译 五. QT基础使用 六. 内核打印Hello world 七. 内核GPIO …

qml中的TextArea使用QSyntaxHighlighter显示高亮语法

效果图&#xff0c;左侧显示行号&#xff0c;右侧用TextArea显示文本内容&#xff0c;并且语法高亮。 2025年5月8号更新 1、多行文本注释 多行文本注释跟普通的高亮规则代码不太一样&#xff0c;代码需要修改&#xff0c;这里以JavaScript举例。 先制定多行文本注释规则&…

【Python从入门到精通】--‘@‘符号的作用

在Python中&#xff0c;符号主要有三种用途&#xff1a;装饰器&#xff08;Decorator&#xff09;、矩阵乘法运算符&#xff08;Python 3.5&#xff09;以及类型提示中的修饰符&#xff08;如typing&#xff09;。 目录 1.--装饰器&#xff08;Decorator&#xff09; 2.--矩…

VAE和Stable Diffusion的关系

文章目录 ✅ 简单回顾&#xff1a;什么是 VAE&#xff1f;&#x1f504; Stable Diffusion 和 VAE 的关系&#xff1a;&#x1f3af; 编码器&#xff1a;&#x1f4a5; 解码器&#xff1a; &#x1f914; 那 Stable Diffusion 本身是 VAE 吗&#xff1f;&#x1f9e0; 简要对比…

PyTorch_点积运算

点积运算要求第一个矩阵 shape:(n, m)&#xff0c;第二个矩阵 shape: (m, p), 两个矩阵点积运算shape为&#xff1a;(n,p) 运算符 用于进行两个矩阵的点乘运算torch.mm 用于进行两个矩阵点乘运算&#xff0c;要求输入的矩阵为3维 &#xff08;mm 代表 mat, mul&#xff09;to…

02_JVM

1、JVM虚拟机组成及内存分配 三大部分&#xff1a; 类装载子系统JVM虚拟机字节码执行引擎 其中&#xff0c;JVM虚拟机运行时数据区&#xff08;内存模型&#xff09;包含五部分&#xff1a;堆、栈&#xff08;线程&#xff09;、方法区&#xff08;元空间&#xff09;、本地…

基于FPGA控制PCF8591开展ADC采样,以采样烟雾模块输出模拟电压为例(IIC通信)

基于FPGA控制PCF8591开展ADC采样 前言一、芯片手册阅读1.设备地址2.字节地址3.IIC通信协议 二、仿真分析三、代码分析总结视频演示 前言 这段时间做设计总是遇到一些传感器模块输出模拟电压&#xff0c;采集模拟电压进而了解传感器输出的浓度占比&#xff0c;在淘宝上找到了一…

在Python和C/C++之间共享std::vector<std::vector<int>>数据

在Python和C/C之间共享std::vector<std::vector>数据 在Python和C/C之间共享嵌套向量数据(std::vector<std::vector<int>>)可以通过几种方法实现。以下是几种常见的方法&#xff1a; 方法1: 使用Cython Cython是连接Python和C的很好选择&#xff0c;它可以…

Linux NVIDIA 显卡驱动安装指南(适用于 RHEL/CentOS)

&#x1f4cc; 一、禁用 Nouveau 开源驱动 NVIDIA 闭源驱动与开源的 nouveau 驱动冲突&#xff0c;需先禁用&#xff1a; if [ ! -f /etc/modprobe.d/blacklist-nouveau.conf ]; thenecho -e "blacklist nouveau\noptions nouveau modeset0" | sudo tee /etc/modpr…

Python爬虫实战:获取千库网各类素材图片,为设计师提供参考

一、引言 在当今设计领域,丰富的素材积累对设计师而言至关重要。千库网作为一个素材资源丰富的平台,拥有海量的各类素材图片。然而,手动从该网站收集素材不仅耗时,而且效率低下。Python 作为一种功能强大的编程语言,具备丰富的库和工具,可用于开发高效的爬虫程序。通过 …

vue截图-html2canvas

使用html2canvas进行截图操作 在 Vue 中使用 ​​html2canvas​​ 将 HTML 元素&#xff08;如包含贝塞尔曲线的 Canvas/SVG&#xff09;转换为图片 下载html2canvas npm install html2canvas在页面中使用&#xff0c;要截取哪个div的内容&#xff0c;先给这个div加一个ref标…

介绍Unity中的Dictionary

在 Unity&#xff08;C#&#xff09;中&#xff0c;Dictionary 是一个非常常用的数据结构&#xff0c;它提供 键值对&#xff08;Key-Value Pair&#xff09; 的存储方式。类似于 Python 的 dict 或 JavaScript 的对象&#xff08;Object&#xff09;&#xff0c;但它是强类型的…