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

XLSX + LuckySheet + LuckyExcel实现前端的excel预览

文章目录

    • 功能简介
    • 简单代码实现
    • 效果
    • 参考

功能简介

  1. 通过LuckyExcel的transformExcelToLucky方法, 我们可以把一个文件直接转成LuckySheet需要的json字符串, 之后我们就可以用LuckySheet预览excel
  2. LuckyExcel只能解析xlsx格式的excel文件,因此对于xls和csv的格式,我们需要通过XLSX来转化成xlsx格式,但在转化过程中会丢失样式
  3. 对于excel中存在很多的空白行,在显示的时候可能会出现卡顿,所以我们需要将过多的空白行移除

简单代码实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Excel File Upload and Preview with Luckysheet</title>
</head>
<body><!-- 文件上传控件 -->
<input type="file" id="fileUpload"/><!-- Luckysheet 的容器 -->
<div id="luckysheet" style="position: relative; width: 100%; height: 500px;"></div>
<script src="https://cdn.jsdelivr.net/npm/xlsx/dist/xlsx.full.min.js"></script><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><script src="https://cdn.jsdelivr.net/npm/luckyexcel/dist/luckyexcel.umd.js"></script><script>const _xlsxType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';const  _xlsType = 'application/vnd.ms-excel';const  _csvType = 'text/csv';//如果后端是以流的方式返回,可以调用这个方法const handleExcel = (res, fileName) => {const file = getExcelFile(res, fileName);handleExcelFile(file);}// 获取Excel文件const getExcelFile = (res, fileName) => {// 根据文件后缀名判断文件类型if (fileName.endsWith('.xlsx')) {return new File([res], fileName, {type: _xlsxType});} else if (fileName.endsWith('.xls')) {return new File([res], fileName, {type: _xlsType});} else if (fileName.endsWith('.csv')) {return new File([res], fileName, {type: _csvType});} else {throw new Error("Unsupported file type");}}// 处理Excel文件const handleExcelFile = (file) => {const fileName = file.name;// 根据文件后缀名判断文件类型并进行处理if (fileName.endsWith('.xlsx')) {console.log("handle excel for xlsx type..", fileName);handleExcelForXlsxType(file, fileName);} else if (fileName.endsWith('.xls') || fileName.endsWith('.csv')) {console.log("handle excel for xls or csv type..", fileName);handleExcelForXlsAndCsvType(file, fileName);} else {throw new Error("Unsupported file type");}}// 处理xlsx类型的Excel文件const handleExcelForXlsxType = (file, fileName) => {const reader = new FileReader();reader.onload = function (event) {const data = new Uint8Array(event.target.result);const workbook = XLSX.read(data, {type: 'array'});// 获取Excel文件中的最大行数let maxRowCountFromExcel = getMaxRowCountFromExcel(workbook);// 如果行数大于100000,则处理Excel文件中的空行if (maxRowCountFromExcel > 1000000) {console.log("excel file has too many blank row..", maxRowCountFromExcel);handleBlankRowForExcelWithTooManyBlankRow(workbook);const xlsxFile = toXlsxExcelFile(workbook, fileName);createLuckySheet(xlsxFile);} else {createLuckySheet(file);}};reader.readAsArrayBuffer(file);}// 处理xls和csv类型的Excel文件const handleExcelForXlsAndCsvType = (file, fileName) => {const reader = new FileReader();// 读取文件完成后的回调函数reader.onload = function (event) {const data = new Uint8Array(event.target.result);// 读取Excel文件内容const workbook = XLSX.read(data, {type: 'array'});// 将Excel文件转换为xlsx类型const xlsxFile = toXlsxExcelFile(workbook, fileName);// 处理xlsx类型的Excel文件handleExcelForXlsxType(xlsxFile, fileName);};// 以ArrayBuffer的形式读取文件reader.readAsArrayBuffer(file);}/ 创建Luckysheetconst createLuckySheet = (file) => {// 销毁已存在的Luckysheetwindow.luckysheet.destroy();// 将Excel文件转换为Luckysheet的jsonLuckyExcel.transformExcelToLucky(file, function (exportJson, luckysheetfile) {if (exportJson.sheets == null || exportJson.sheets.length === 0) {throw new Error("Failed to load excel file");}// 创建Luckysheet的配置项const options = {container: 'luckysheet',data: exportJson.sheets, // title: exportJson.info.name,// userInfo: exportJson.info.name.creator,column: 10,row: 10,showinfobar: false,sheetFormulaBar: true,showConfigWindowResize: false};// 创建Luckysheetwindow.luckysheet.create(options);});}// 获取Excel文件中的最大行数const getMaxRowCountFromExcel = (workbook) => {let maxRowCount = 0;if (workbook.SheetNames == null || workbook.SheetNames.length === 0) {return maxRowCount;}// 遍历每个sheet,获取最大行数workbook.SheetNames.forEach(sheetName => {const worksheet = workbook.Sheets[sheetName];if (worksheet['!ref'] === undefined) {return;}const range = XLSX.utils.decode_range(worksheet['!ref']);maxRowCount = maxRowCount + range.e.r;});console.log("max:", maxRowCount)return maxRowCount;}const reduceBlankRow = (row, range, worksheet) => {// 从给定的行开始,向上遍历到工作表的起始行while (row > range.s.r) {// 假设当前行是空的let allEmpty = true;// 遍历当前行的所有列for (let col = range.s.c; col <= range.e.c; col++) {// 获取当前单元格的引用const cell_ref = XLSX.utils.encode_cell({c: col, r: row});// 如果当前单元格不为空,则将allEmpty设置为false并跳出循环if (worksheet[cell_ref]) {allEmpty = false;break;}}// 如果当前行是空的,则将行数减一,否则跳出循环if (allEmpty) {row--;} else {break;}}// 更新工作表范围的结束行range.e.r = row;// 更新工作表的范围引用worksheet['!ref'] = XLSX.utils.encode_range(range.s, range.e);}// 处理Excel文件中的空行const handleBlankRowForExcelWithTooManyBlankRow = (workbook) => {if (workbook.SheetNames == null || workbook.SheetNames.length === 0) {return;}// 遍历每个sheet,处理空行workbook.SheetNames.forEach(sheetName => {const worksheet = workbook.Sheets[sheetName];if (worksheet['!ref'] === undefined) {return;}const range = XLSX.utils.decode_range(worksheet['!ref']);let row = range.e.r;reduceBlankRow(row, range, worksheet);});}// 将Excel文件转换为xlsx类型const toXlsxExcelFile = (workbook, fileName) => {const newWorkbook = XLSX.write(workbook, {bookType: 'xlsx', type: 'binary'});const data = new Uint8Array(newWorkbook.length);for (let i = 0; i < newWorkbook.length; i++) {data[i] = newWorkbook.charCodeAt(i);}return new File([data], fileName, {type: _xlsxType});}// 文件上传控件的change事件处理函数document.getElementById('fileUpload').addEventListener('change', function (e) {// 获取上传的文件const file = e.target.files[0];// 处理Excel文件handleExcelFile(file);});</script></body>
</html>

效果

在这里插入图片描述

参考

https://juejin.cn/post/7211805251216031801
https://segmentfault.com/a/1190000043720845
https://juejin.cn/post/7232524757525659708
https://blog.csdn.net/q2qwert/article/details/130908294
https://www.cnblogs.com/ajaemp/p/12880847.html
https://blog.csdn.net/weixin_40775791/article/details/135409716
https://blog.csdn.net/u013113491/article/details/129106671

相关文章:

XLSX + LuckySheet + LuckyExcel实现前端的excel预览

文章目录 功能简介简单代码实现效果参考 功能简介 通过LuckyExcel的transformExcelToLucky方法&#xff0c; 我们可以把一个文件直接转成LuckySheet需要的json字符串&#xff0c; 之后我们就可以用LuckySheet预览excelLuckyExcel只能解析xlsx格式的excel文件&#xff0c;因此对…...

在Ubuntu上创建和启用交换文件的简单步骤

文章目录 为什么使用交换文件&#xff1f;步骤 1&#xff1a;创建交换文件步骤 2&#xff1a;设置正确的权限步骤 3&#xff1a;将文件格式化为交换空间步骤 4&#xff1a;启用交换文件步骤 5&#xff1a;验证交换文件步骤 6&#xff1a;永久启用交换文件步骤 7&#xff1a;调整…...

Java [ 基础 ] HashMap详解 ✨

目录 ✨探索Java基础 HashMap详解✨ 总述 主体 1. HashMap的基本概念 2. HashMap的工作原理 3. HashMap的常用操作 4. HashMap的优缺点 总结 常见面试题 常见面试题解答 1. HashMap的底层实现原理是什么&#xff1f; 2. 如何解决HashMap中的哈希冲突&#xff1f;…...

vue2项目迁移vue3与gogocode的使用

#背景 公司有个项目使用vue2jswebpack框架开发的&#xff0c;由于该项目内部需要安扫&#xff0c;导致很多框架出现了漏洞需要升级&#xff0c;其中主要需要从vue2升vue3,但是重新搭框架推翻重做成本太高&#xff0c;于是找到了gogocode。 #升级步骤踩坑 1. 安装 gogocode插…...

【Python123题库】#数列求和 #百分制成绩转换五分制(循环) #正负交错数列前n项和 #求数列前n项的平方和

禁止转载&#xff0c;原文&#xff1a;https://blog.csdn.net/qq_45801887/article/details/140079866 参考教程&#xff1a;B站视频讲解——https://space.bilibili.com/3546616042621301 有帮助麻烦点个赞 ~ ~ Python123题库 数列求和百分制成绩转换五分制(循环)正负交错数列…...

Edge浏览器选中后,出现AI智能生成 AI专业写作

这个是扩展里边的“ 网页万能复制 & ChatGPT AI写作助手”造成的&#xff0c;这个拓展增加了AI写作功能。关闭这个拓展就解决了。...

c++习题08-计算星期几

目录 一&#xff0c;问题 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;问题 二&#xff0c;思路 首先&#xff0c;需要注意到的是3^2000这个数值很大&#xff0c;已经远远超过了long long 数据类型能够表示的范围&#xff0c;如果想要使用指定的数据类型来保存…...

单目相机减速带检测以及测距

单目相机减速带检测以及测距项目是一个计算机视觉领域的应用&#xff0c;旨在使用一个摄像头&#xff08;单目相机&#xff09;来识别道路上的减速带&#xff0c;并进一步估计车辆与减速带之间的距离。这样的系统对于智能驾驶辅助系统&#xff08;ADAS&#xff09;特别有用&…...

Xilinx FPGA:vivado实现乒乓缓存

一、项目要求 1、用两个伪双端口的RAM实现缓存 2、先写buffer1&#xff0c;再写buffer2 &#xff0c;在读buffer1的同时写buffer2&#xff0c;在读buffer2的同时写buffer1。 3、写端口50M时钟&#xff0c;写入16个8bit 的数据&#xff0c;读出时钟25M&#xff0c;读出8个16…...

解决 VM 虚拟机网络连接异常导致的 Finalshell 无法连接及 ifconfig 中 ens33 丢失问题

在使用 VM 虚拟机的过程中&#xff0c;遇到了一个颇为棘手的网络连接问题。平时虚拟机都能够正常启动并使用&#xff0c;但昨天在启用虚拟机时更换了一下网络节点&#xff0c;结果今天打开虚拟机后。Finalshell 无法连接上虚拟机&#xff0c;并且输入 ifconfig 命令后也没有 en…...

深入Django(三)

Django视图&#xff08;Views&#xff09;详解 引言 在前两天的博客中&#xff0c;我们介绍了Django的基本概念和模型系统。今天&#xff0c;我们将深入探讨Django的视图&#xff08;Views&#xff09;&#xff0c;它们是处理用户请求和返回响应的地方。 什么是Django视图&a…...

观测云赋能「阿里云飞天企业版」,打造全方位监控观测解决方案

近日&#xff0c;观测云成功通过了「阿里云飞天企业版」的生态集成认证测试&#xff0c;并荣获阿里云颁发的产品生态集成认证证书。作为监控观测领域的领军者&#xff0c;观测云一直专注于提供统一的数据视角&#xff0c;助力用户构建起全球范围内的端到端全链路可观测服务。此…...

51单片机第27步_单片机工作在睡眠模式

重点学习51单片机工作在睡眠模式。 1、进入“睡眠模式”的方法 通过将PCON寄存器中的PDWN置1&#xff0c;则CPU会进入“睡眠模式”。在“睡眠模式”中,晶振将停止工作&#xff0c;因此&#xff0c;定时器和串口都将停止工作&#xff0c;只有外部中断继续工作。如果单片机电源…...

互联网应用主流框架整合之SpringCloud微服务治理

微服务架构理念 关于微服务的概念、理念及设计相关内容&#xff0c;并没有特别严格的边界和定义&#xff0c;某种意义上说&#xff0c;适合的就是最好的&#xff0c;在之前的文章中有过详细的阐述&#xff0c;微服务[v1.0.0][Spring生态概述]、微服务[设计与运行]、微服务[v1.…...

超快的 Python 包管理工具「GitHub 热点速览」

天下武功&#xff0c;无坚不破&#xff0c;唯快不破&#xff01; 要想赢得程序员的欢心&#xff0c;工具的速度至关重要。仅需这一优势&#xff0c;即可使其在众多竞争对手中脱颖而出&#xff0c;迅速赢得开发者的偏爱。以这款号称下一代极速 Python 包管理工具——uv 为例&…...

网络基础:OSPF 协议

OSPF&#xff08;Open Shortest Path First&#xff09;是一种广泛使用的链路状态路由协议&#xff0c;用于IP网络中的内部网关协议&#xff08;IGP&#xff09;。OSPF通过在网络中的所有路由器之间交换路由信息&#xff0c;选择从源到目的地的最优路径。OSPF工作在OSI模型的第…...

1456.定长子串中元音的最大数目

思路&#xff1a; 首次是滑动窗口&#xff0c; 然后遍历子字符串&#xff0c;这样复杂度太高&#xff0c;没过测试 改进&#xff0c;滑动窗口先求出第一个窗口中元音数量&#xff0c; 然后利用滑动式&#xff0c;一进一出方式判断首尾是否是原因即可 给你字符串 s 和整数 k 。 …...

基于xilinx FPGA的GTX/GTH/GTY位置信息查看方式(如X0Y0在bank几)

目录 1 概述2 参考文档3 查看方式4查询总结&#xff1a; 1 概述 本文用于介绍如何查看xilinx fpga GTX得位置信息&#xff08;如X0Y0在哪个BANK/Quad&#xff09;。 2 参考文档 《ug476_7Series_Transceivers》 《pg156-ultrascale-pcie-gen3-en-us-4.4》 3 查看方式 通过…...

JAVA小知识30:JAVA多线程篇1,认识多线程与线程安全问题以及解决方案。(万字解析)

来 多线程&#xff0c;一个学起来挺难但是实际应用不难的一个知识点&#xff0c;甚至在很多情况下都不需要考虑&#xff0c;最多就是写测试类的时候模拟一下并发&#xff0c;现在我们就来讲讲基础的多线程知识。 一、线程和进程、并发与并行 1.1、线程和进程 线程&am…...

Python数据分析案例47——笔记本电脑价格影响因素分析

案例背景 博主对电脑的价格和配置一直略有研究&#xff0c;正好最近也有笔记本电脑相关的数据&#xff0c;想着来做点分析吧&#xff0c;写成一个案例。基本上描述性统计&#xff0c;画图&#xff0c;分组聚合&#xff0c;机器学习&#xff0c;交叉验证&#xff0c;搜索超参数…...

LLM API安全攻防实战:从提示词注入到自动化测试方案

1. 项目概述&#xff1a;被忽视的LLM API安全前线最近在帮几个团队做上线前的安全审计&#xff0c;发现一个挺有意思的现象&#xff1a;大家对于传统API的鉴权、限流、SQL注入这些常规检查已经形成了肌肉记忆&#xff0c;但一旦涉及到LLM&#xff08;大语言模型&#xff09;的A…...

古戏台构件声学特性的时域有限差分方法【附模型】

✨ 长期致力于时域有限差分法、窑洞、戏台、八字墙、共形技术研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;曲面共形网格快速生成算法&#xff1a; …...

软阴影:那个让虚拟世界“温柔起来“的光影小秘密

一、从一只小猫的影子说起 前几天我在朋友家做客&#xff0c;他家养了一只胖乎乎的橘猫&#xff0c;正趴在阳台的窗边晒太阳。我无意间瞥了一眼那只猫脚边的影子&#xff0c;突然被一个细节震撼了—— 那只猫的影子——并不是一片均匀的黑。 仔细看——猫肚子紧贴地板的地方——…...

自制射频功率计:基于AD8317芯片,成本43欧元实现1MHz-10GHz测量

1. 项目概述&#xff1a;为什么我要亲手打造一台射频功率计在无人机和模型飞行器的圈子里&#xff0c;尤其是在我们荷兰FMS Spaarnwoude俱乐部&#xff0c;合规飞行是头等大事。我给我的八轴飞行器加装了云台相机和图传系统&#xff0c;工作在5.8GHz频段。根据本地法规&#xf…...

Windows 10/11系统下,SecureCRT 8.7.2保姆级安装与激活图文指南(含Keygen使用避坑点)

Windows平台SecureCRT 8.7.2全流程部署与安全配置指南在当今远程运维与网络管理的日常工作中&#xff0c;一款可靠的终端仿真工具如同工程师的瑞士军刀。作为行业标杆的SecureCRT&#xff0c;其8.7.2版本在Windows 10/11环境下的部署却常让新手陷入各种技术陷阱——从安装路径选…...

【DeepSeek开源协议识别权威指南】:20年合规专家亲授3大协议陷阱与5步精准识别法

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek开源协议识别的底层逻辑与合规价值 DeepSeek系列模型&#xff08;如DeepSeek-V2、DeepSeek-Coder&#xff09;虽以“开源”名义发布&#xff0c;但其实际许可状态需通过结构化协议解析才能准确…...

Postgresql基础实践教程(八)

⭐️⭐️⭐️⭐️⭐️ 完整数据详见 练习数据免费 ⭐️⭐️⭐️⭐️⭐️ 六十九、查找会员ID 27的向上推荐链 问题 查找会员ID 27的向上推荐链&#xff1a;即推荐该会员的人&#xff0c;以及推荐那个人的人&#xff0c;依此类推。返回会员ID、名字和姓氏。按会员ID降序排列。…...

2026 文章代码高亮方案选型

将基于 Prism.js 或 Highlight.js 的传统高亮方案与基于 Shiki 的现代化高亮方案进行对比&#xff0c;其核心区别在于底层解析原理的不同&#xff08;正则表达式 vs. TextMate 语法树&#xff09;。 以下是两种方案的底层原理、各自优缺点、核心对比矩阵以及适用场景的详细分析…...

如何快速掌握MoveIt2:面向ROS 2开发者的工业机器人运动规划完整指南

如何快速掌握MoveIt2&#xff1a;面向ROS 2开发者的工业机器人运动规划完整指南 【免费下载链接】moveit2 :robot: MoveIt for ROS 2 项目地址: https://gitcode.com/gh_mirrors/mo/moveit2 想要为你的机器人实现智能运动规划吗&#xff1f;MoveIt2作为ROS 2生态中最强大…...

CUDA并行计算与FSR框架优化实践

1. CUDA并行计算与FSR框架概述在GPU加速计算领域&#xff0c;CUDA&#xff08;Compute Unified Device Architecture&#xff09;作为NVIDIA推出的并行计算平台和编程模型&#xff0c;已经成为高性能计算的事实标准。其核心设计理念是将计算任务分解为网格&#xff08;Grid&…...