前端轻松实现文件预览(pdf、excel、word、图片)
需求:实现一个在线预览pdf、excel、word、图片等文件的功能。
介绍:支持pdf、xlsx、docx、jpg、png、jpeg。
以下使用Vue3代码实现所有功能,建议以下的预览文件标签可以在外层包裹一层弹窗。
图片预览
iframe标签能够将另一个HTML页面嵌入到当前页面中,我们的图片也能够使用iframe标签来进行展示。
<iframe :src="图片地址"style="z-index: 1000; height:650px; width: 100%; margin: 0 auto"sandbox="allow-scripts allow-top-navigation allow-same-origin allow-popups"
>
「sandbox」这个属性如果是单纯预览图片可以不使用,该属性对呈现在 iframe 框架中的内容启用一些额外的限制条件。属性值可以为空字符串(这种情况下会启用所有限制),也可以是用空格分隔的一系列指定的字符串。
- allow-scripts: 允许嵌入的浏览上下文运行脚本(但不能创建弹窗)。如果没有使用该关键字,就无法运行脚本。
- allow-top-navigation: 允许将框架内所加载页面中的超链接导航到父级窗口
- allow-same-popups: 允许弹窗 (例如 window.open, target=“_blank”)。如果没有使用该关键字,相应的功能将自动被禁用。
- allow-same-origin: 如果没有使用该关键字,嵌入的浏览上下文将被视为来自一个独立的源,这将使 same-origin policy 同源检查失败。使用了这个属性,那么当前页面和iframe打开的页面视为同源。
word文档预览(docx)
// 先下载npm包
npm i docx-preview --save
<div class="docxRef"></div><script>
import { renderAsync } from 'docx-preview';function fn() {
// 这里的res.data是 blob文件流,如果自己的不是blob文件流
// 可以通过URL.createObjectURL(参数) 参数为File格式,转换为blob文件流let blob = res.datalet childRef = document.getElementsByClassName('docxRef');renderAsync(blob, childRef[0]) //渲染
}
fn()</script>

预览excel文件(xlsx)
下载包
npm install xlsx@0.16.0
<div class="xlsxClass"></div>
const reader = new FileReader();
//通过readAsArrayBuffer将blob转换为ArrayBuffer对
reader.readAsArrayBuffer(res.data) // 这里的res.data是blob文件流
reader.onload = (event) => {// 读取ArrayBuffer数据变成Uint8Arrayvar data = new Uint8Array(event.target.result);// 这里的data里面的类型和后面的type类型要对应var workbook = XLSX.read(data, { type: "array" });var sheetNames = workbook.SheetNames; // 工作表名称var worksheet = workbook.Sheets[sheetNames[0]];// var excelData = XLSX.utils.sheet_to_json(worksheet); //JSONlet html = XLSX.utils.sheet_to_html(worksheet);document.getElementsByClassName('xlsxClass')[0].innerHTML = html
};
pdf预览
使用第三方包
下载包 npm install pdfjs-dist
我使用的是npm install pdfjs-dist@2.0.943版本,以下例子使用的是vue3+vite创建的项目
以下例子通过canvas来渲染pdf
<template><div class="box"><div class="tool-bar"><div>{{ pdfParams.pageNumber }} / {{ pdfParams.total }}</div><button type="primary" :disabled="pdfParams.pageNumber == pdfParams.total" @click="nextPage">下一页</button><button type="primary" :disabled="pdfParams.pageNumber == 1" @click="prevPage">上一页</button></div><canvas id="pdf-render"></canvas></div>
</template>
<script setup>
import { onMounted, ref, reactive } from 'vue'
const pdfParams = reactive({pageNumber: 1, // 当前页total: 0, // 总页数
});// 不要定义为ref或reactive格式,就定义为普通的变量
let pdfDoc = null;
// 这里必须使用异步去引用pdf文件,直接去import会报错,也不知道为什么
onMounted(async ()=> {let pdfjs = await import('pdfjs-dist/build/pdf')let pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry')pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker// 此文件位于public/test2.pdflet url = ref('/test2.pdf')pdfjs.getDocument(url.value).promise.then(doc => {pdfDoc = docpdfParams.total = doc.numPagesgetPdfPage(1)})
})// 加载pdf的某一页
const getPdfPage = (number) => {pdfDoc.getPage(number).then(page => {const viewport = page.getViewport()const canvas = document.getElementById('pdf-render')const context = canvas.getContext('2d')canvas.width = viewport.viewBox[2]canvas.height = viewport.viewBox[3]viewport.width = viewport.viewBox[2]viewport.height = viewport.viewBox[3]canvas.style.width = Math.floor(viewport.width) + 'px'canvas.style.height = Math.floor(viewport.height) + 'px'let renderContext = {canvasContext: context,viewport: viewport,// 这里transform的六个参数,使用的是transform中的Matrix(矩阵)transform: [1, 0, 0, -1, 0, viewport.height]}// 进行渲染page.render(renderContext)})
}
// 下一页功能
const prevPage = () => {if(pdfParams.pageNumber > 1) {pdfParams.pageNumber -= 1} else {pdfParams.pageNumber = 1}getPdfPage(pdfParams.pageNumber)
}
// 上一页功能
const nextPage = () => {if(pdfParams.pageNumber < pdfParams.total) {pdfParams.pageNumber += 1} else {pdfParams.pageNumber = pdfParams.total}getPdfPage(pdfParams.pageNumber)
}
</script>
以上pdf代码引用文章:(54条消息) 前端pdf预览、pdfjs的使用_pdf.js_无知的小菜鸡的博客-CSDN博客
pdfjs官方代码:例子 (mozilla.github.io)
以上代码看不懂的地方可以查阅官方代码,大部分都是固定的写法。
「以上注意点:」
- 必须异步引用pdf的文件!!!
- pdf演示文件位于public/test2.pdf
- transform: [1, 0, 0, -1, 0, viewport.height],使用了transform中的Matrix(矩阵)
- 下一页和上一页功能都需要重新渲染
使用原生
<!-- 这个url 是生成的链接地址,正常的话浏览器地址也可以打开 --><object :data="url" type="application/pdf"></object><script>let base64 = '后端返回的base64数据' //你要传入的base64数据let bstr = atob(base64)let n = bstr.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}//确定解析格式,可能可以变成img,没有深入研究let blob = new Blob([u8arr], { type: 'application/pdf;chartset=UTF-8' })let url = window.URL.createObjectURL(blob)
相关文章:
前端轻松实现文件预览(pdf、excel、word、图片)
需求:实现一个在线预览pdf、excel、word、图片等文件的功能。 介绍:支持pdf、xlsx、docx、jpg、png、jpeg。 以下使用Vue3代码实现所有功能,建议以下的预览文件标签可以在外层包裹一层弹窗。 图片预览 iframe标签能够将另一个HTML页面嵌入到…...
docker服务器、以及容器设置自动启动
一、docker服务设置自动启动 查看已启动的服务 systemctl list-units --typeservice 查看是否设置开机启动 systemctl list-unit-files | grep enable设置开机启动 systemctl enable docker.service关闭开机启动 systemctl disable docker.service 二、docker容器设置自…...
k8s集群证书过期后,如何更新k8s证书
对于版本 1.21.5,这是我的解决方案: 步骤1: ssh 到主节点,然后在步骤 2 中检查证书。 步骤2: 运行这个命令:kubeadm certs check-expiration rootkube-master-1:~# kubeadm certs check-expiration [c…...
5.6.webrtc三大线程
那今天呢?我们来介绍一下web rtc的三大线程,那为什么要介绍这三大线程呢?最关键的原因在于web rtc的所有其他线程都是由这三大线程所创建的。那当我们将这三个线程理解清楚之后呢?我们就知道其他线程与它们之间是怎样关系…...
@Slf4j报错:Not generating field log: A field with same name already exists
错误出处: 错误原因: 同时使用了Slf4j注解以及LittlecLogger private static final LittlecLogger log LittlecLoggerFactory.getLogger(TimeTrackController.class); 修复方法: 将log改为LOG,便于区分,代码即用到了…...
乖宝宠物上市,能否打破外资承包中国宠物口粮的现实
近日,乖宝宠物上市了,这是中国宠物行业成功挂牌的第三家公司。同时,昨日,宠物行业最大的盛事“亚洲宠物展”时隔3年,于昨日在上海成功回归。 这两件事情的叠加可谓是双喜临门,行业能够走到今天实属不易&…...
Ubuntu安装Apache+Php
环境:ubuntu 22.04 虚拟机 首先更新一下 sudo apt-get update sudo apt-get upgrade安装Apache2: sudo apt-get install apache2 输入y,继续。等着他恐龙抗浪抗浪的下载安装就好了 打开浏览器访问http://localhost/ 安装php: …...
open cv学习 (四)图像的几何变换
图像的几何变换 demo1 # dsize实现缩放 import cv2 img cv2.imread("./cat.jpg") dst1 cv2.resize(img, (100, 100)) dst2 cv2.resize(img, (400, 400)) # cv2.imshow("img", img) # cv2.imshow("dst1", dst1) # cv2.imshow("dst2&quo…...
matlab 检测点云中指定尺寸的矩形平面
目录 一、概述1、算法概述2、主要函数二、代码示例三、结果展示四、参数解析输入参数名称-值对应参数输出参数五、参考链接一、概述 1、算法概述 detectRectangularPlanePoints:检测点云中指定尺寸的矩形平面 <...
HCIP——STP配置案例
STP配置案例 一、简介二、实现说明1、华为实现说明2、其他厂商实现 三、STP原理1、协商原则2、角色和状态3、报文格式4、BPDU报文处理流程4.1 BPDU报文的分类4.2 BPDU报文的处理流程4.3 BPDU报文格式 四、使用注意事项五、配置举例1、组网需求2、配置思路3、操作步骤4、配置文件…...
JCTools Mpsc源码详解(二) MpscArrayQueue
MpscArrayQueue是一个固定大小的环形数组队列,继承自ConcurrentCircularArrayQueue MpscArrayQueue的特点: 环形队列底层数据结构为数组有界 看一下MpscArrayQueue的属性(填充类除外)--- //生产者索引 private volatile long producerIndex; //生产者边界 private volatile…...
前端面试的性能优化部分(13)每天10个小知识点
目录 系列文章目录前端面试的性能优化部分(1)每天10个小知识点前端面试的性能优化部分(2)每天10个小知识点前端面试的性能优化部分(3)每天10个小知识点前端面试的性能优化部分(4)每天…...
C++ STL无序关联式容器(详解)
STL无序关联式容器 继 map、multimap、set、multiset 关联式容器之后,从本节开始,再讲解一类“特殊”的关联式容器,它们常被称为“无序容器”、“哈希容器”或者“无序关联容器”。 注意,无序容器是 C 11 标准才正式引入到 STL 标…...
Python爬虫解析工具之xpath使用详解
文章目录 一、数据解析方式二、xpath介绍三、环境安装1. 插件安装2. 依赖库安装 四、xpath语法五、xpath语法在Python代码中的使用 一、数据解析方式 爬虫抓取到整个页面数据之后,我们需要从中提取出有价值的数据,无用的过滤掉。这个过程称为数据解析&a…...
Linux防火墙报错:Failed to start firewalld.service Unit is masked
Linux防火墙报错:Failed to start firewalld.service: Unit is masked. 1、故障现象: 启动防火墙失败,报错情况如下: systemctl start firewalld # 报错: Failed to start firewalld.service: Unit is masked.原因是…...
前端面试:【Vuex】Vue.js的状态管理利器
嗨,亲爱的Vuex探险家!在Vue.js开发的旅程中,有一个强大的状态管理库,那就是Vuex。Vuex是Vue.js的官方状态管理工具,通过State、Mutation、Action和Module等核心概念,协助你轻松管理应用的状态。 1. 什么是V…...
Kotlin协程runBlocking并发launch,Semaphore同步1个launch任务运行
Kotlin协程runBlocking并发launch,Semaphore同步1个launch任务运行 <dependency><groupId>org.jetbrains.kotlinx</groupId><artifactId>kotlinx-coroutines-core</artifactId><version>1.7.3</version><type>pom&…...
c++ Union之妙用
union的作用基本是它里面的变量都用了同一块内存,跟起了别名一样,类型不一样的别名。 基本用法: struct Union{union {float a;int b;};};Union u;u.a 2.0f;std::cout << u.a << "," << u.b << std::endl…...
JSON的处理
1、JSON JSON(JavaScript Object Notation):是一种轻量级的数据交换格式。 它是基于 ECMAScript 规范的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写&#…...
matlab使用教程(20)—插值基础
1.网格和散点样本数据 插值是在位于一组样本数据点域中的查询位置进行函数值估算的方法。函数值是根据最接近查询点的样本数据点计算的。MATLAB 根据样本数据的结构,可以执行两种插值。样本数据可以形成网格,也可以是分散的。 网格化的样本数据使得插值…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
