当前位置: 首页 > news >正文

vue3中预览Excel文件

1.前言

有时候项目中需要预览Excel文件,特别是对于.xls格式的Excel文件许多插件都不支持,经过尝试,最终有三种方案可以实现.xlsx和.xls格式的Excel文件的预览,各有优缺点

2.luckyexcel插件

2.1说明

该插件优点在于能保留源文件的样式和保留图片,缺点在于只支持.xlsx,无法编辑更改(可能是我没有去查找资料),适用于需要保留样式只用于预览不用于编辑的场景

2.2使用过程

2.2.1安装
npm install luckyexcel
2.2.2引入

引入方式有两种

(1)使用CDN引入
<script src="https://cdn.jsdelivr.net/npm/luckyexcel/dist/luckyexcel.umd.js"></script>

这个路径意思是会拉取到最新的luckysheet代码,但是如果Luckysheet刚刚发布,jsdelivr网站可能还没来得及从npm上同步过去,故而使用这个路径还是会拉到上一个版本,我们推荐您直接指定版本。

<script src="https://cdn.jsdelivr.net/npm/luckysheet@2.1.12/dist/luckysheet.umd.js"></script>
(2)本地静态文件方式引入

先从luckyexcel项目中获静态资源用https://gitcode.com/gh_mirrors/lu/Luckyexcel

在public文件夹中新建luckyexcel文件夹,将静态资源全部放入该文件夹中

两种引入方式前提都已说明,下面开始引入

在项目入口文件index.html中引入

// 实用CDN方式引入-拉取最新代码<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"><link rel="icon" href="/favicon.ico"><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/css/pluginsCss.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/plugins.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/css/luckysheet.css' /><link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/assets/iconfont/iconfont.css' /><script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/js/plugin.js"></script><script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js"></script><title>kanno</title>
</head>
// 使用静态文件方式引入
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"><link rel="icon" href="/favicon.ico"><link rel='stylesheet' href='/luckyexcel/plugins/css/pluginsCss.css' /><link rel='stylesheet' href='/luckyexcel/plugins/plugins.css' /><link rel='stylesheet' href='/luckyexcel/css/luckysheet.css' /><link rel='stylesheet' href='/luckyexcel/assets/iconfont/iconfont.css' /><script src="/luckyexcel/plugins/js/plugin.js"></script><script src="/luckyexcel/luckysheet.umd.js"></script><title>kanno</title>
</head>
2.2.3使用
<template><div id="luckysheet" ref="luckysheet" style="width:100%;height:100%;position: absolute;left: 0;top: 0;z-index: 0;" ></div>
</template><script setup>
import LuckyExcel from 'luckyexcel'
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue';
const props = defineProps({excelUrl: {default:'',type: String}
});// const emit = defineEmits([]);
let { excelUrl } = toRefs(props)onMounted(()=>{viewOpen('Excel文件')
})
async function viewOpen(fileName) {const data = await fetchBlob(excelUrl.value);console.log("excelUrl.value",excelUrl.value);if (!data) {console.log("无法获取文件数据");return;}LuckyExcel.transformExcelToLucky(data, function (exportJson, luckysheetfile) {if (!exportJson || exportJson.sheets == null || exportJson.sheets.length == 0) {console.log("出错了");return;}if (window.luckysheet) {window.luckysheet.destroy();}window.luckysheet.create({data: exportJson.sheets,title: fileName,userInfo: exportJson.info?.creator,container: 'luckysheet', // 设定DOM容器的idshowtoolbar: false, // 是否显示工具栏showinfobar: false, // 是否显示顶部信息栏showstatisticBar: false, // 是否显示底部计数栏sheetBottomConfig: false, // sheet页下方的添加行按钮和回到顶部按钮配置allowEdit: false, // 是否允许前台编辑enableAddRow: false, // 是否允许增加行enableAddCol: false, // 是否允许增加列sheetFormulaBar: false, // 是否显示公式栏enableAddBackTop: false, // 返回头部按钮showsheetbar: false, // 是否显示底部sheet页按钮showsheetbarConfig: {add: false,menu: false}});});
}async function fetchBlob(url) {try {const response = await fetch(url);if (!response.ok) throw new Error("Network response was not ok.");return await response.blob();} catch (error) {console.error("Failed to fetch blob:", error);return null;}
}
</script>
2.2.4效果

3.微软在线查看excel文件

3.1说明

微软在线查看excel是使用iframe嵌入微软查看的页面,有点在于开发简单,能支持.xlsx和.xls格式,缺点在于无法编辑(可能通过注册微软账号可以进行编辑)和限制文件大小在5M以下,需要文件能通过链接访问,适用于小文件查看

3.2使用

<iframe id="iframeId" scrolling="no" frameborder="0" width="100%" height="118%"style="margin-top: -80px;"></iframe>
let iframeId = document.getElementById('iframeId')
iframeId.src = `https://view.officeapps.live.com/op/view.aspx?src=` + encodeURIComponent(data.data.fileUrl) // 微软网页

3.3代码说明

Your request has been blocked. This could be due to several reasons.是微软用来在线查看excel文件的网页;encodeURIComponent()方法是用来解析文件地址,无需引入

3.4效果展示

4.使用XLSX插件

4.1说明

XLSX支持.xlsx和.xls格式的Excel文件的预览,能通过js方法来更改excel表格,可操作性好,缺点在于不能保留源文件样式、渲染出来的表格和源文件有出入,适用于简单表格文件的预览

4.2安装
npm install xlsx
4.3引入使用
<template><div :id="'excelDom'+id" style="width: 100%;height: 100%;overflow: auto;"></div>
</template><script setup>
import * as XLSX from "xlsx";
import axios from "axios";
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue';
const props = defineProps({excelUrl: {default: '',type: String},id:{default: 1,type: Number}
});// const emit = defineEmits([]);
let { excelUrl,id } = toRefs(props)// Excel显示
getFileObjectFromUrl(excelUrl.value, function (file) {loadExcelAndRender(file);
});
function getFileObjectFromUrl(url, callback) {var xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.responseType = 'blob'; // 重要:设置响应类型为blobxhr.onload = function () {if (this.status === 200) {// 请求成功,this.response包含Blob对象var blob = this.response;let fileName = new Date().getTime()// 创建File对象var file = new File([blob], fileName + '.xlsx', { type: blob.type });// 调用回调函数,传入File对象callback(file);} else {console.error('Failed to download file:', this.status);}};xhr.onerror = function () {console.error('Request error');};xhr.send();
}
async function loadExcelAndRender(file) {try {const reader = new FileReader();reader.onload = function (e) {let excelDom = document.getElementById('excelDom'+id.value);const data = new Uint8Array(e.target.result);const workbook = XLSX.read(data, { type: 'array' });const firstSheetName = workbook.SheetNames[0]; // 获取第一个sheet的名称const worksheet = workbook.Sheets[firstSheetName];const html = XLSX.utils.sheet_to_html(worksheet, { id: firstSheetName }); // 只渲染第一个sheetexcelDom.innerHTML = html; // 将HTML渲染到指定的div中// 动态添加细线表格样式const table = excelDom.querySelector('table');if (table) {// 设置表格整体样式table.style.borderCollapse = 'collapse'; // 合并边框table.style.width = '100%'; // 宽度占满容器table.style.fontSize = '12px'; // 字体大小table.style.lineHeight = '1.5'; // 行高table.style.textAlign = 'center'; // 文字居中table.style.border = '1px solid #ddd'; // 外边框细线// 设置表头样式const thead = table.querySelector('tr');if (thead) {thead.style.backgroundColor = '#f2f2f2'; // 表头背景颜色thead.style.fontWeight = 'bold'; // 表头字体加粗thead.style.whiteSpace = 'nowrap'; // 防止内容换行,确保宽度自适应}// 设置单元格样式const cells = table.querySelectorAll('td, th');cells.forEach(cell => {cell.style.border = '1px solid #ddd'; // 细线边框cell.style.padding = '5px'; // 内边距});// 为所有非表头的 td 添加点击事件const tds = table.querySelectorAll('tbody td'); // 获取 tbody 中的 tdtds.forEach((td) => {td.addEventListener('click', () => {// 清除所有单元格的背景色tds.forEach(cell => {cell.style.backgroundColor = ''; // 清除背景色});// 为当前点击的单元格设置背景色td.style.backgroundColor = '#cfe2ff'; // 设置背景色为浅蓝色// 计算行号和列号const row = td.parentNode.rowIndex; // 获取行号(从 0 开始)const col = td.cellIndex; // 获取列号(从 0 开始)});});}};reader.readAsArrayBuffer(file);} catch (error) {console.error('Error loading or rendering Excel:', error);}
}</script>

相关文章:

  • Spring三级缓存的作用与原理详解
  • 【每天一个知识点】意图传播(Intent Propagation)
  • 单例模式深度解析:从原理到高阶应用实践
  • 文章记单词 | 第89篇(六级)
  • jvm第一篇《内存与垃圾回收》学习笔记第一章jvm初始
  • 计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
  • [MySQL排查] “Too many connections“ 错误?数据库最大连接数满了怎么办及优化
  • 我的 PDF 工具箱:CodeBuddy 打造 PDFMagician 的全过程记录
  • Jenkins教程
  • C#将1GB大图裁剪为8张图片
  • Ngrok 配置:实现 Uniapp 前后端项目内网穿透
  • vue使用Fabric和pdfjs完成合同签章及批注
  • 解决LeetCode 47. 全排列 II 问题的正确姿势:深入分析剪枝与状态跟踪
  • MySQL的 JOIN 优化终极指南
  • ES(Elasticsearch)的应用与代码示例
  • 股指期货贴水为何会产生成本?
  • WebSocket聊天室的简单制作指南
  • qt文本边框设置
  • 保安员考试报名时,体检项目包含哪些?
  • Spyglass:跨时钟域同步(同步使能)
  • 美国失去最后的AAA主权评级,继标普、惠誉后再遭穆迪降级
  • 美国新泽西客运公司遭遇罢工:40年来首次,35万人受影响
  • 大环线呼之欲出,“金三角”跑起来了
  • 中国青年报:为见义勇为者安排补考,体现了教育的本质目标
  • 娃哈哈:调整产销布局致部分工厂停工,布局新产线可实现自主生产,不排除推新品牌
  • 证券时报:中美互降关税落地,订单集中补发港口将迎高峰期