前端轻松实现文件预览(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 根据样本数据的结构,可以执行两种插值。样本数据可以形成网格,也可以是分散的。 网格化的样本数据使得插值…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...