luckyexcel 编辑预览excel文件
luckyexcel 编辑预览excel文件
支持后端传文件流预览编辑,也支持选择本地文件编辑预览
看效果

上代码
<template><div style="margin: 30px"><div class="button-box2"><div><div style="color: red">当前弹框不要修改列名称,如需修改,请去列管理页面修改列。</div></div><div><a-space><!-- <input id="uploadBtn" type="file" @change="loadExcel3" /> --><a-button type="primary" @click="downExcel">导出模板</a-button><a-uploadv-model:file-list="data.fileList"accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":customRequest="customUpload"name="file":multiple="false":showUploadList="false"><a-button :loading="data.clientLoading" type="primary">客户端导入</a-button></a-upload><a-buttontype="primary":loading="data.serverLoading"@click="() => (modal.visible = true)">服务端导入</a-button><!-- <a-dropdown><template v-slot:overlay><a-menu><a-menu-item key="1"><a-uploadv-model:file-list="data.fileList"accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":customRequest="customUpload"name="file":multiple="false":showUploadList="false"><div :loading="data.clientLoading">客户端导入</div></a-upload></a-menu-item><a-menu-item key="2"><div :loading="data.serverLoading" @click="() => (modal.visible = true)">服务端导入</div></a-menu-item></a-menu></template><a-button type="primary">导入预览(如果这样写的话就要把loading放到这里,统一一个变量就好了)<DownOutlined /></a-button></a-dropdown> --></a-space></div></div><div id="luckysheet"></div><div class="button-box"><a-space><a-button @click="cancel"> 取消 </a-button><a-button type="primary" :loading="loading" @click="downloadExcel">确定 </a-button></a-space></div><div class="tips"><div style="color: red" v-if="data.isShowDataType">测序方法请填写:Nanopore pod5,Nanopore fast5,Nanopore fastq,齐碳fastq,PacBio_CCS,PacBio_CLR,华大,illumina,ABI,其他</div><div style="color: red" v-if="data.isShowDataType">类型请填写:细菌,病毒,真菌,16S,宏基因组,动植物,转录组,人源,其他</div><div style="color: red" v-if="data.isShowDataType">日期请按照YYYY-MM-DD格式填写,如:2024-01-01</div></div><a-modal:visible="modal.visible"title="选择文件"width="1020px"@ok="fileOk"@cancel="() => (modal.visible = false)"zIndex="1000"destroyOnClose><FileSelect /></a-modal></div>
</template><script lang="ts" setup>
import { reactive, onMounted, watch } from 'vue';
import * as Api from '/@/serve/api/samples/samples';
import { exportExcel } from '/@/utils/utils/exceljs';
import FileSelect from '/@/components/FileSelector/index.vue';
import { DownOutlined } from '@ant-design/icons-vue';
import LuckyExcel from 'luckyexcel';
import xlsx from 'node-xlsx';import { message } from 'ant-design-vue';
const emit = defineEmits(['cancel', 'batchAddData']);
const props = defineProps({headers: {type: Array,default: () => [],},loading: {type: Boolean,default: false,},
});
const modal = reactive({visible: false,
});
const cancel = () => {luckysheet.exitEditMode(); // 退出编辑模式emit('cancel', '');
};
//服务器导入确定
const fileOk = () => {let selectPath = localStorage.getItem('nowSelector');if (selectPath) {if (selectPath.indexOf(' ') != -1) {message.warning('所选路径不能包含空格');return;}if (selectPath.slice(-5).includes('.xlsx')) {loadExcel2(selectPath);modal.visible = false;} else {message.info('请选择xlsx文件');}}
};
const loadExcel2 = (filePath: string) => {let params = { filePath };Api.xlsxFile(params).then((res: any) => {const blob = new Blob([res], {// 设置返回的文件类型type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',});let file = new window.File([blob], 'fileName.xlsx', {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',});data.serverLoading = true;loadExcel([file]);}).catch(() => {message.error('error');});
};
const loadExcel3 = (evt: any) => {loadExcel(evt.target.files);
};
//自定义上传
const customUpload = (info: any) => {data.clientLoading = true;loadExcel([info.file]);
};const isFunction = (val: Function) => {return Object.prototype.toString.call(val).slice(8, -1) === 'Function';
};const loadExcel = (files: any) => {//通过接口获取文件流,将文件流转为file文件,if (files == null || files.length == 0) {message.info('没有文件等待导入');return;}let name = files[0].name;let suffixArr = name.split('.'),suffix = suffixArr[suffixArr.length - 1];if (suffix != 'xlsx') {message.error('目前只支持导入xlsx文件');return;}LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {if (exportJson.sheets == null || exportJson.sheets.length == 0) {message.error('读取excel文件内容失败,目前不支持xls文件!');return;}//销毁原有的表格isFunction(luckysheet?.destroy) && luckysheet.destroy();luckysheet.create({container: 'luckysheet', //luckysheet is the container idlang: 'zh', // 设定表格语言showinfobar: false,data: exportJson.sheets,title: exportJson.info.name,userInfo: exportJson.info.name.creator,});console.log('start loading');data.clientLoading = false;data.serverLoading = false;});
};
const downExcel = () => {let result = xlsx.build([{ name: 'sheet1', data: [props.headers] }]);const ab = Buffer.from(result, 'binary');const blob = new Blob([ab]);const blobUrl = URL.createObjectURL(blob);const a = document.createElement('a');a.href = blobUrl;a.download = '模版.xlsx';a.click();window.URL.revokeObjectURL(blobUrl);// exportExcel(luckysheet.getAllSheets(), '模板');
};
const downloadExcel = () => {// console.log(luckysheet.getAllSheets());// exportExcel(luckysheet.getAllSheets(), '下载');luckysheet.exitEditMode(); // 退出编辑模式let data = luckysheet.getAllSheets()[0].celldata;console.log(data);let result: any[] = [];data.forEach((item: any) => {if (result.length > item.r) {let tempArray = result[item.r];// console.log('item.c', item.c);tempArray[item.c] = item.v.m;} else {let tempArray = [];for (let i = 0; i < props.headers.length; i++) {tempArray.push(undefined);}tempArray[item.c] = item.v.m;result.push(tempArray);}});// let result2 = result.map((item: any) => {// return item.slice(0, props.headers.length);// });// console.log(result2);emit('batchAddData', result);
};const data = reactive({options: {},fileList: [],clientLoading: false,serverLoading: false,isShowDataType: false,
});
// !!! create luckysheet after mounted
onMounted(() => {drawSheet();
});watch(() => props.headers,(n) => {drawSheet();},
);const drawSheet = () => {console.log('111');data.isShowDataType = props.headers.includes('测序方法');let celldata = props.headers.map((item: any, index: number) => {let con = {r: 0,c: index,v: {bl: 1,ct: { fa: 'General', t: 'g' },ht: 0,v: item,m: item,},};return con;});data.options = {container: 'luckysheet',lang: 'zh', // 设定表格语言showinfobar: false,data: [{name: 'Sheet1', //工作表名称color: '', //工作表颜色index: 0, //工作表索引status: 1, //激活状态order: 0, //工作表的下标hide: 0, //是否隐藏row: 36, //行数column: 36, //列数defaultRowHeight: 39, //自定义行高defaultColWidth: 146, //自定义列宽celldata, //初始化使用的单元格数据config: {merge: {}, //合并单元格rowlen: {}, //表格行高columnlen: {}, //表格列宽rowhidden: {}, //隐藏行colhidden: {}, //隐藏列borderInfo: {}, //边框authority: {}, //工作表保护},scrollLeft: 0, //左右滚动条位置scrollTop: 0, //上下滚动条位置luckysheet_select_save: [], //选中的区域calcChain: [], //公式链isPivotTable: false, //是否数据透视表pivotTable: {}, //数据透视表设置filter_select: {}, //筛选范围filter: null, //筛选配置luckysheet_alternateformat_save: [], //交替颜色luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色luckysheet_conditionformat_save: {}, //条件格式frozen: {}, //冻结行列配置chart: [], //图表配置zoomRatio: 1, // 缩放比例image: [], //图片showGridLines: 1, //是否显示网格线dataVerification: {}, //数据验证配置},// {// name: 'Sheet2',// color: '',// index: 1,// status: 0,// order: 1,// celldata: [// {// r: 0,// c: 0,// v: {// v: '暂时淀粉',// m: '暂时淀粉',// },// },// {// r: 0,// c: 1,// v: {// v: 1,// ct: {// fa: 'General',// t: 'n',// },// m: '1',// },// },// {// r: 1,// c: 0,// v: {// v: 10,// ct: {// fa: 'General',// t: 'n',// },// m: '10',// },// },// {// r: 1,// c: 1,// v: {// v: 11,// ct: {// fa: 'General',// t: 'n',// },// m: '11',// },// },// ],// config: {},// },],};isFunction(luckysheet?.destroy) && luckysheet.destroy();luckysheet.create(data.options);
};
</script><style scoped>
#luckysheet {/* position: relative; */width: 79vw;height: 70vh;
}
.button-box {/* margin: 20px; */margin-top: 20px;display: flex;justify-content: flex-end;
}
.button-box2 {margin: 20px;display: flex;/* justify-content: flex-end; */justify-content: space-between;
}
.tips {margin-top: -30px;
}
:deep(.luckysheet-wa-editor) {overflow: hidden;
}
:deep(.luckysheet-stat-area) {background-color: transparent;
}
</style>
<style>
#chat-assistant-container {display: none;
}
</style>相关文章:
luckyexcel 编辑预览excel文件
luckyexcel 编辑预览excel文件 支持后端传文件流预览编辑,也支持选择本地文件编辑预览 看效果 上代码 <template><div style"margin: 30px"><div class"button-box2"><div><div style"color: red">…...
记录Java使用websocket
实现场景:每在小程序中添加一条数据时,后台将主动推送一个标记给PC端,PC端接收到标记将进行自动播放音频。 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import or…...
(javaweb)分层解耦
目录 一.三层架构 二.分层解耦 三.IOC&DI入门 四.IOC详解 五. DI详解 一.三层架构 复用性差,难以维护和管理 前端发起请求,先会到达controller,再调用service进行逻辑处理,逻辑处理的前提是先拿到数据,到dao…...
2024华为数通HCIP-datacom最新题库(H12-831变题更新⑨)
请注意,华为HCIP-Datacom考试831已变题 请注意,华为HCIP-Datacom考试831已变题 请注意,华为HCIP-Datacom考试831已变题 近期打算考HCIP的朋友注意了,如果你准备去考试,还是用的之前的题库,切记暂缓。 如…...
PCIe学习笔记(21)
读请求的数据返回(Data Return for Read Requests) •针对内存读取请求的单个完成可能提供少于请求的全部数据量,只要对于给定请求的所有完成在组合起来时返回了读取请求中请求的数据量。 ◦不同请求的完成不能合并。 ◦I/O和Configuratio…...
分享Embedding 模型微调的实现
写在前面 \1. 当前比较主流的Embedding开源模型有哪些? 答:1. m3e(Moka Massive Mixed Embedding) 2. BAAI/bge-large-zh-v1.5。更多的开源模型评测榜单可见: https://huggingface.co/spaces/mteb/leaderboard \2. 模型的作用? …...
TED: 1靶场复现【附代码】(权限提升)
机下载地址: Ted: 1 ~ VulnHubTed: 1, made by Avraham Cohen. Download & walkthrough links are available.https://www.vulnhub.com/entry/ted-1,327/ 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.59.0/24|grep -B 2 00:0C…...
Python(TensorFlow)衍射光学层卷积算法模拟(英伟达GPU)
🎯要点 🎯衍射光学卷积算法模拟 | 🎯模拟或数字电子计算之前加入一层光学计算 | 🎯前馈卷积神经网络计算成像系统对输入图像进行分类 | 🎯相位掩模利用线性空间不变成像系统执行固有卷积 📜用例 Python非…...
iOS开发进阶(二十二):Xcode* 离线安装 iOS Simulator
文章目录 一、前言二、模拟器安装 一、前言 Xcode 15 安装包的大小相比之前更小,因为除了 macOS 的 Components,其他都需要动态下载安装,否则提示 iOS 17 Simulator Not Installed。 如果不安装对应的运行模拟库,真机和模拟器无法…...
Prostgresql的Timescaledb插件/扩展部署
背景:研发需求,需要把docker部署得postgresql迁移到新的节点并要求再本地部署,提前查看数据库需要那些插件,并进行安装,docker部署的默认有插件。 版本对比:postgresql版本对应某个Timescaledb版本 我得p…...
分布式知识总结(一致性Hash算法)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 一致性Hash算法 假如有三台服务器编号node0、node1、node2&…...
图数据库在社交网络分析中的应用
随着社交网络的飞速发展,用户之间的关系变得日益复杂。传统的关系型数据库由于其表结构的限制,难以高效地处理和查询这些复杂的网络数据。图数据库以其独特的图模型结构,能够更好地表示和分析社交网络中的关系,因而在社交网络分析…...
Git基础使用教程
版本控制手册 本文中出现的 [ ] 为根据需求自行修改的变量。 基本命令 git init:将当前目录配置成git仓库,信息记录在隐藏的.git文件夹中。 git config --global user.name [xxx]:设置全局用户名,信息记录在~/.gitconfig文件中。…...
技术速递|Python in Visual Studio Code 2024年8月发布
排版:Alan Wang 我们很高兴地宣布 Visual Studio Code 的 Python 和 Jupyter 扩展将于 2023 年 8 月发布! 此版本包括以下公告: 面向贡献者的 Python 扩展开发容器用于运行带有参数的 Python 文件的调试配置Python 扩展 API 的 Npm 包容错 …...
【话题】重塑未来:AI辅助编程对程序员工作的影响与应对策略
目录 人工智能时代,程序员如何保持核心竞争力? 引言 方向一:AI辅助编程对程序员工作的影响 效率提升 代码质量 潜在风险 方向二:程序员应重点发展的核心能力 复杂系统设计 跨学科知识整合 与AI协作的能力 方向三:人机协…...
在Debian上安装freeswitch
在Debian上安装freeswitch 说明: 首次发表日期:2024-08-12参考文档: https://medium.com/jogikrunal9477/ultimate-guide-to-installing-freeswitch-on-ubuntu-22-04-lts-3745ef6a6bd6https://developer.signalwire.com/freeswitch/FreeSWI…...
论文分享 | Fuzz4All: 基于大语言模型的通用模糊测试
大语言模型是当前最受关注的研究热点,基于其生成和理解能力,对现有领域在提升性能和效果上做更多尝试。分享一篇发表于2024年ICSE会议的论文Fuzz4All,它组合多个大语言模型以非常轻量且黑盒的方式,实现了一种跨语言和软件的通用模…...
VS Code 配置docker 管理员权限终端
问题描述 在容器中需要使用sudo或者su root时候,权限不够,被灵魂提问。 然而,镜像是官方发布的,翻遍了githubissues也没有找到password. 解决 Attach shell 在docker插件中,attach shell 可以直接获得shell。 所…...
使用Linux实现FTP云盘1
关于FTP服务器 FTP(文件传输协议)服务器是在互联网上提供文件存储和访问服务的计算机,它们依照FTP 协议提供服务。 FTP是File Transfer Protocol(文件传输协议)。 程序运行,服务端不断接收客户端指令,服务 端可同时处…...
tombo resquiggle
Re-squiggle 算法 简介 纳米孔读取产生的电流信号水平数据称为squiggle。将这些squiggle信息进行基底呼叫通常与参考序列相比会包含一些错误。Re-squiggle算法定义了从squiggle到参考序列的新分配,即重新squiggle。 Re-squiggle算法是Tombo框架的基础。该算法输入包含原始信…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
