H5实现PDF文件预览,使用pdf.js-dist进行加载
H5实现PDF文件预览,使用pdf.js-dist进行加载
一、应用场景
在H5平台上预览PDF文件是在原本已经开发完成的系统中新提出的需求,原来的系统业务部门是在PC端进行PDF的预览与展示,但是现在设备进行了切换,改成了安卓一体机进行文件预览。因此出现了PDF文件无法显示的问题,此前使用的是vue-pdf插件和PDFObject插件实现的预览,所以这两个插件是无法实现PDF预览了,改为了pdfjs-dist进行PDF的预览。
二、实现方法
法一:通过js代码实现预览
该方法适用于预览后端返回的文件流内容,但是此方法是将pdf展示在画布上,因此无法选中或复制文本内容。
1、定义一个容器用来展示PDF
这个容器可以是div,也可以是canvas,由于pdfjs渲染pdf文件是一页一页进行展示的,因此需要循环进行展示。
<template><div><canvas v-for="pageIndex in pdfPages" :id="`pdf-canvas-` + pageIndex" :key="pageIndex" style="display: block;width:100%"></canvas></div>
</template>
2、加载pdf
由于我这边的文件来自于后端返回的文件流,因此我需要将base64进行转换后进行展示。
<script lang="ts" setup>
import { getDocument } from 'pdfjs-dist'
import * as pdfjsLib from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.mjs'
let pdfDoc = reactive({}); // 保存加载的pdf文件流
let pdfPages = ref(0); // pdf文件的页数
let pdfScale = ref(1.0); // 缩放比例const pdfLoader = async () => {//...此处为接口请求,返回的res.data.result.fileByte为pdf的文件流内容pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js';const blob = new Blob([res.data.result.fileByte], { type: 'application/pdf' });let arrayBuffer = base64ToBuffer(res.data.result.fileByte);const loadingTask = pdfjsLib.getDocument(arrayBuffer);loadingTask.promise.then((pdf) => {pdfDoc = pdf; //获取pdf文档流pdfPages.value = pdf.numPages; //获取pdf文件的页数renderPage(1);//从第几页开始渲染});
}
//渲染pdf文件
const renderPage = (num) => {pdfDoc.getPage(num).then((page) => {const canvasId = 'pdf-canvas-' + num;const canvas = document.getElementById(canvasId);const ctx = canvas.getContext('2d');const dpr = window.devicePixelRatio || 1;const bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;const ratio = dpr / bsr;const viewport = page.getViewport({ scale: pdfScale.value });canvas.width = viewport.width * ratio;canvas.height = viewport.height * ratio;canvas.style.width = viewport.width + 'px';canvas.style.height = viewport.height + 'px';ctx.setTransform(ratio, 0, 0, ratio, 0, 0);const renderContext = {canvasContext: ctx,viewport: viewport,};page.render(renderContext);if (num < pdfPages.value) {renderPage(num + 1);}});
};
</script>
法二:通过内置的viewer.html文件进行预览
该方法适用于pdf在本地,或者是通过后端返回url链接的,操作比较简单, 不需要操作API,而且可以复制pdf中的文本内容,如果需要修改部分功能的话,可以直接修改html中的代码进行实现。
1、下载pdf.js官方插件
打开官网的链接(链接地址),找到下方的Stable按钮,下载稳定版本的插件包。

2、将下载后的文件放到项目中
将下载后的压缩包解压后,会看到这两个文件夹,将这两个文件夹添加到项目中。

其中在web文件夹中有一个viewer.html文件,下面将借助这个封装好的文件实现pdf的预览。实现原理是将文件的路径传给viewer.html,从而解析该文件进行预览。
如果你的文件在本地,那么可以把这个文件放到与viewer.html同一个路径下,然后实现预览。
window.open("./js/pdfJS/web/viewer.html?file=/pdf/files/compressed.tracemonkey-pldi-09.pdf");//注意路径是否正确
如果你的文件是通过后端拿到的URL,那么需要修改后面的pdf文件的路径,注意需要提前将路径转码。
let fileUrl = encodeURIComponent('http:.....xxx.pdf') //将路径转码
window.open("http:...viewer.html?file=" + fileUrl);
三、注意事项
pdf.js无法直接在本地预览文件,需要启动服务器才能运行,例如tomcat、live-server 插件等。查阅相关资料后,发现是因为 pdf.js 渲染 pdf 文档时使用了 Web Worker 技术,该 Web Worker 无法读取本地文件。
相关文章:
H5实现PDF文件预览,使用pdf.js-dist进行加载
H5实现PDF文件预览,使用pdf.js-dist进行加载 一、应用场景 在H5平台上预览PDF文件是在原本已经开发完成的系统中新提出的需求,原来的系统业务部门是在PC端进行PDF的预览与展示,但是现在设备进行了切换,改成了安卓一体机进行文件…...
面试域——面试系统工程
摘要 1. 当前就业面试场景 1.1. 招聘市场的“551 定律” 你知道招聘市场的“551 定律”吗? 551 定律:每一层筛选环节都会有百分之十的折损率。一个岗位从接收简历到发下 Offer 至少要筛选 500 份左右的简历、面试 50 人左右、只有 5 人左右通过面试&am…...
PHP-FPM 性能配置优化
4 核 8 G 服务器大约可以开启 500 个 PHP-FPM,极限吞吐量在 580 qps (Query Per Second 每秒查询数)左右。 Nginx php-fpm 是怎么工作的? php-fpm 全称是 PHP FastCGI Process Manager 的简称,从名字可得知ÿ…...
渗透测试-百日筑基—SQL注入篇时间注入绕过HTTP数据编码绕过—下
day8-渗透测试sql注入篇&时间注入&绕过&HTTP数据编码绕过 一、时间注入 SQL注入时间注入(也称为延时注入)是SQL注入攻击的一种特殊形式,它属于盲注(Blind SQL Injection)的一种。在盲注中,攻击…...
Unity - UGUI动静分离
原理:UGUI 是基于Canvas来进行合并计算的 1.不同Cavans的UI元素,是无法合批渲染,无法实现同一个drawcall 2. 每次合批的时候,会合并计算Canvas下所有的UI元素 , 具体流程: Step1: 对Cavans下所有的UI元素进行合批计算 Step2: …...
arm 体系架构-过程调用约定
ref: ARM体系结构学习笔记:过程调用标准AAPC、 ARM32调用约定、ARM64调用约定_arm64 传参 结构体-CSDN博客 ARM软件逆向工程入门 01 - ARM调用约定(Calling Convention)_armv7函数调用约定-CSDN博客 ARM学习(17&…...
STM32基于LL库的USART+DMA使用
时隔两年半再次更新LL库,本次带来USART DMA 实现接收不定长。 1、开发思路 使用USART DMA接收不定长的功能的思路是:借助USART的空闲中断、DMA发送完成中断。 打开F103的手册可得知,USART的空闲中断触发条件是在接收完成后触发࿰…...
设计模式06-结构型模式1(适配器/桥接/组合模式/Java)
#1024程序员节|征文# 4.1 适配器模式 结构型模式(Structural Pattern)的主要目的就是将不同的类和对象组合在一起,形成更大或者更复杂的结构体。结构性模式的分类: 类结构型模式关心类的组合,由多个类…...
【损害和风险评估&坑洼】路面坑洼检测系统源码&数据集全套:改进yolo11-DCNV3
改进yolo11-DLKA等200全套创新点大全:路面坑洼检测系统源码&数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.24 注意:由于项目一直在更新迭代,上面“1.图片效果展示”和“2.视频效果展示”展示的系统图片或者视频可…...
GenAI 生态系统现状:不止大语言模型和向量数据库
自 20 个月前 ChatGPT 革命性的推出以来,生成式人工智能(GenAI)领域经历了显著的发展和创新。最初,大语言模型(LLMs)和向量数据库吸引了最多的关注。然而,GenAI 生态系统远不止这两个部分&#…...
gitlab 配置ssh keys
settings -- 终端配置: git config --global user.email "yxthotmail.cm" 配置gitlab 账号邮箱 git config --global user.name "xt.yao" 配置gitlab账号用户名 生成SSH key,输入命令ssh-keygen -t rsa,一直按回车…...
小程序开发实战:PDF转换为图片工具开发
目录 一、开发思路 1.1 申请微信小程序 1.2 编写后端接口 1.3 后端接口部署 1.4 微信小程序前端页面开发 1.5 运行效果 1.6 小程序部署上线 今天给大家分享小程序开发系列,PDF转换为图片工具的开发实战,感兴趣的朋友可以一起来学习一下!…...
我有两台120kw充电桩一天能赚多少钱
(当前是理想状态下,当然还要看场地费用,还有物业,变压器,等等) ———————————————————— ———————————————————— 要计算两台120kW充电桩能赚多少钱,我们…...
深入了解 Android 中的命名空间:`xmlns:tools` 和其他常见命名空间
在 Android 开发中,xmlns (.xml的namespace)命名空间是一个非常重要的概念。通过引入不同的命名空间,可以使用不同的属性来设计布局、设置工具属性或者支持自定义视图等。除了 xmlns:tools 以外,还有很多常见的命名空间…...
stable-zero123模型构建指南
一、介绍 stabilityai出品,能够对有简单背景的物体进行三维视角图片的生成,简单来说也就是通过调整变换观察的视角生成对应视角的图片。 本项目通过comfyui实现。 二、容器构建说明 1. 部署ComfyUI (1)使用命令克隆ComfyUI g…...
算法题解记录32+++最长连续序列(百题筑基)
你们好,我是蚊子码农,好久不见。由于秋招求职的繁琐事情,我有很长一段时间没更新博客,希望我的粉丝们能够谅解。 秋招我拿到了一些offer,最终决定去一个主要做“网络安全”业务的公司工作,也许明天会更好&a…...
全球知名度最高的华人起名大师颜廷利:世界顶级思想哲学教育家
全国给孩子起名最好的大师颜廷利教授在其最新的哲学探索中,提出了《升命学说》这一前沿理论观点,该理论不仅深刻地回应了古今中外众多哲学流派和思想体系的精髓,还巧妙地融合了实用主义、理想主义以及经验主义的核心理念。通过这一独特的视角…...
Flink Rest API
REST API | Apache Flink Flink官网API 通过curl 或者Rest API工具测试web UI对应的接口返回信息 Flink 提交yarn任务 ./bin/flink run -t yarn-per-job historyServer ../bin/historyserver.sh start...
Zig 语言通用代码生成器:逻辑,冒烟测试版发布二
Zig 语言通用代码生成器:逻辑,冒烟测试版发布二 Zig 语言是一种新的系统编程语言,其生态位类同与 C,是前一段时间大热的 rust 语言的竞品。它某种意义上的确非常像 rust,尤其是在开发过程中无穷无尽抛错的过程&#x…...
mysql 通过GROUP BY 聚合并且拼接去重另个字段
我的需求: 我想知道同一个手机号出现几次,并且手机号出现在哪些地方。下面是要的效果。 源数据: CREATE TABLE bank (id bigint(20) unsigned NOT NULL AUTO_INCREMENT,user_id int(11) NOT NULL DEFAULT 0,tel varchar(255) COLLATE utf8mb4_unicode_…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
