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 无法读取本地文件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记一次真实项目的性能问题诊断、优化(阿里云redis分片带宽限制问题)过程

前段时间&#xff0c;接到某项目的压测需求。项目所有服务及中间件&#xff08;redis、kafka&#xff09;、pg库全部使用的阿里云。 压测工具&#xff1a;jmeter(分布式部署)&#xff0c;3组负载机&#xff08;每组1台主控、10台linux 负载机&#xff09; 问题现象&#xff1…

基于SSM的网上购物系统的设计与实现

技术介绍 本系统运用了JSP技术、SSM框架、B/S架构和myspl数据库 MySQL 介绍 MySQL是一种关系型的数据库管理系统&#xff0c;属于Oracle旗下的产品。MySQL的语言是非结构化的&#xff0c;使用的用户可以在数据上进行工作。这个数据库管理系统一经问世就受到了社会的广泛关注…

神仙公司名单(成都)

神仙公司&#xff08;成都&#xff09; 神仙公司&#xff0c;继续。 最近对古城很感兴趣&#xff0c;加上前两周吃的串串还记忆犹新&#xff0c;这期写一下四川省省会&#xff1a;成都。 在互联网人眼中&#xff0c;成都似乎是一个存在感很低的城市&#xff0c;但实际上成都一直…

【电机控制】相电流重构——单电阻采样方案

【电机控制】相电流重构——单电阻采样方案 文章目录 [TOC](文章目录) 前言一、基于单电阻采样电流重构技术原理分析1.1 单电阻采样原理图1.2 基本电压矢量与电流采样关系 二、非观测区2.1 扇区过渡区2.2 低压调制区 三、非观测区补偿——移相法四、参考文献总结 前言 使用工具…

C语言实现栈和队列

代码已经上传我的资源&#xff0c;需要可自取 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&…

Python实现贝叶斯优化器(Bayes_opt)优化简单循环神经网络分类模型(SimpleRNN分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 贝叶斯优化器 (BayesianOptimization) 是一种黑盒子优化器&#xff0c;用来寻找最优参数。 贝叶斯…

Linux资源与网络请求

参数说明&#xff1a; d : 改变显示的更新速度&#xff0c;或是在交谈式指令列( interactive command)按 sq : 没有任何延迟的显示速度&#xff0c;如果使用者是有 superuser 的权限&#xff0c;则 top 将会以最高的优先序执行c : 切换显示模式&#xff0c;共有两种模式&#…

软件测试岗位,职业前景到底怎样?

最近经常被问到软件测试这个行业的前景&#xff0c;网上也有大量唱衰测试这个行业的声音&#xff0c;很多选择职业方向的同学对是否要进入这个职业也非常迷茫。 所以开一贴来聊一聊秋草对软件测试这个岗位的要求以及对其前景的看法。 软件测试到底是个什么样的岗位&#xff1…

如何学习cuda编程?

第一本cuda教材: CUDA By Example​ developer.nvidia.com/cuda-example 配套网课&#xff1a; Udacity CS344: Intro to Parallel Programming​ developer.nvidia.com/udacity-cs344-intro-parallel-programming 记得做网课作业。 然后就靠项目上手了。 我当时实习时候的项…

ProTable样式缺失

在使用Ant Design Pro开发页面时&#xff0c;想要引用ProComponents组件中的ProTable表格&#xff0c;引入官方文档的案例发现缺少样式 官方文档地址ProTable - 高级表格 - ProComponents (ant.design) 引入的是第一个Demos 样式预览&#xff1a; 代码 import { EllipsisO…

今天不分享技术,分享秋天的故事

引言 这个爱情故事好像是个悲剧&#xff0c;你说的是婚姻。爱情没有悲剧&#xff0c;对爱者而言&#xff0c;爱情怎么会是悲剧呢。对春天而言&#xff0c;秋天是它的悲剧吗。结尾是什么&#xff0c;等待&#xff0c;之后呢&#xff0c;没有之后。或者说&#xff0c;等待的结果…

Spring Cloud微服务

Spring Cloud 是一个专注于微服务架构的一站式解决方案&#xff0c;它通过整合多个优秀的开源框架和工具&#xff0c;为开发者提供了构建、管理和维护微服务系统所需的全方位支持。以下是关于 Spring Cloud 微服务的详细介绍&#xff1a; 基本概念 微服务架构&#xff1a;微服务…

图像处理算法的形式

一 基本功能形式 按图像处理的输出形式&#xff0c;图像处理的基本功能可分为三种形式。 1&#xff09;单幅图像 -------->单幅图像 2&#xff09;多幅图像-------->单幅图像 3&#xff09;单(或多)幅图像------->数字或符号符 二 几种具体算法形式 1.局部处理 …

搭建 mongodb 副本集,很详细

搭建 mongodb 副本集&#xff0c;很详细 一、前言二、创建用户1、创建 root 用户2、创建测试用户3、修改用户密码 三、修改配置文件&#xff08;主节点&#xff09;1、开启登录认证2、加上副本集3、最终配置文件 四、副本节点1、创建副本节点目录2、编辑配置文件3、启动副本节点…

力扣283-- 移动零

开始做梦的地方 力扣283 &#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 何解&#xff1f; 1&#xff0c;暴力枚举&#xff1a…

JS面试八股文(一)

&#x1f60a;JS面试八股文&#xff08;一&#xff09; 1.JS由哪三部分组成&#xff1f;2.JS有哪些内置对象&#xff1f;3.操作数组的方法有哪些&#xff1f;4.JS对数据类型的检测方式有哪些&#xff1f;5.说一下闭包&#xff0c;闭包有什么特点&#xff1f;6.前端的内存泄漏怎…

adb常见指令以及问题解决

1.屏幕截图 问题&#xff1a; /system/bin/sh: pull: not found 最后是一个美元符号$&#xff0c;则表示不是以root身份运行&#xff1b; 最后是一个井号#&#xff0c;则表示是以root身份运行。 解决方案&#xff1a; 直接退出&#xff0c;在PC端使用adb pull&#xff0c;而…

Spring Boot实现的动态化酒店住宿管理系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理酒店客房管理系统的相关信息成为必然。开发…

软件设计师考试大纲整理

为了防止出题者不按常理出牌&#xff0c;此文档为根据上午题大纲自行整理的扩展知识&#xff0c;并非考试常考题 此文档为根据上午题大纲自行整理的扩展知识&#xff0c;并非考试常考题 此文档为根据上午题大纲自行整理的扩展知识&#xff0c;并非考试常考题 闲暇时间了解知…

Web高级开发实验:EL基本运算符与数据访问

一、实验目的 掌握EL的定义&#xff0c;即Expression Language&#xff0c;用于提高编程效率。学习和掌握在开发环境中创建Java文件&#xff0c;并在jsp文件中使用EL表达式去调用其中的方法与属性等。 二、实验所用方法 上机实操 三、实验步骤及截图 1、创建javaweb项目&a…