vue项目前端生成EXCEL模板并解析上传JSON

一,安装依赖      并引入 

        "file-saver": "^2.0.5",

        "xlsx": "^0.18.5"

        import { saveAs } from "file-saver";

二,生成模板

button_23Click() {const self = this;// 导入模板下载// const tableData = ['菜单id', '菜单编码', '菜单别名', '功能模块ID', '功能ID', '父菜单', '显示顺序', '是否是叶子节点', '创建时间'];// const tableField = ['menuId', 'menuText', 'menuAlias', 'functionModuleId', 'functionId', 'parentId', 'seq', 'isLeaf', 'createTime'];const tableData = ["姓名","用户账户","性别","最大会话数","手机号","微信账号",];const tableField = ["staffName","userAccount","sex","maxSessions","mobile","weChat",];const columns = [];for (let i = 0; i < tableData.length; i++) {const excelCol = {};// excelCol.header = tableData[0][i];excelCol.key = tableField[i];excelCol.width = 30;columns.push(excelCol);}const Excel = require("exceljs");const workbook = new Excel.Workbook();const worksheet = workbook.addWorksheet("sheet1");const fileName = "data.xlsx";workbook.created = new Date();workbook.modified = new Date();worksheet.columns = columns;const colArray = [];const tableHead = [];let level = 1;let maxLevel = 1;tableHead.push({title: "姓名",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const staffNameIndex = tableField.indexOf("staffName");const staffNameIdLetter = excelDownloadForArea(staffNameIndex);colArray.push({letter: staffNameIdLetter,horizontal: "center",dataType: "string",});tableHead.push({title: "用户账户",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const userAccountIdIndex = tableField.indexOf("userAccount");const userAccountIdIdLetter = excelDownloadForArea(userAccountIdIndex);colArray.push({letter: userAccountIdIdLetter,horizontal: "center",dataType: "string",});tableHead.push({title: "性别",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const sexIndex = tableField.indexOf("sex");const sexIdLetter = excelDownloadForArea(sexIndex);colArray.push({letter: sexIdLetter,horizontal: "center",dataType: "string",});tableHead.push({title: "最大会话数",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const maxSessionsIdIndex = tableField.indexOf("maxSessions");const maxSessionsIdIdLetter = excelDownloadForArea(maxSessionsIdIndex);colArray.push({letter: maxSessionsIdIdLetter,horizontal: "center",dataType: "string",});tableHead.push({title: "手机号",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const telephoneIdIndex = tableField.indexOf("mobile");const telephoneIdIdLetter = excelDownloadForArea(telephoneIdIndex);colArray.push({letter: telephoneIdIdLetter,horizontal: "center",dataType: "string",});tableHead.push({title: "微信账号",horizontal: "center",colspan: 1,rowspan: 1,level: level,});const weChatIdIndex = tableField.indexOf("weChat");const weChatIdIdLetter = excelDownloadForArea(weChatIdIndex);colArray.push({letter: weChatIdIdLetter,horizontal: "center",dataType: "string",});--level;for (let i = 0; i < tableHead.length; i++) {if (tableHead[i].level > maxLevel) {maxLevel = tableHead[i].level;}}for (let i = 0; i < tableHead.length; i++) {if (tableHead[i].rowspan + tableHead[i].level - 1 > maxLevel) {tableHead[i].rowspan = maxLevel - tableHead[i].level + 1;}}const excelCell = [];const rows = [];for (let i = 0; i < tableField.length; i++) {for (let j = 0; j < maxLevel; j++) {const cell = { xAxis: i, yAxis: j, isEdit: false };excelCell.push(cell);}}for (let i = 0; i < maxLevel; i++) {let x = 0;const row = [];for (let j = 0; j < tableHead.length; j++) {const index = excelCell.findIndex(function (value, index, arr) {return value.isEdit === false && value.yAxis === i;});if (index !== -1) {x = excelCell.find(function (value, index, arr) {return value.isEdit === false && value.yAxis === i;}).xAxis;}if (tableHead[j].level - 1 === i) {const startArea = excelDownloadForArea(x) + (1 + i);const endArea =excelDownloadForArea(x + tableHead[j].colspan - 1) +(tableHead[j].rowspan + i);for (let k = x; k < x + tableHead[j].colspan; k++) {for (let m = i; m < tableHead[j].rowspan + i; m++) {excelCell.find(function (value, index, arr) {return value.xAxis === k && value.yAxis === m;}).isEdit = true;}}while (row.length < x) {row.push("");}row[x] = tableHead[j].title;tableHead[j].merge = startArea + ":" + endArea;}}rows.push(row);}worksheet.insertRows(1, rows);for (let j = 0; j < tableHead.length; j++) {worksheet.mergeCells(tableHead[j].merge);worksheet.getCell(tableHead[j].merge.split(":")[0]).alignment = {vertical: "middle",horizontal: tableHead[j].horizontal,};}for (let i = 0; i < colArray.length; i++) {for (let j = maxLevel + 1; j < 1000; j++) {worksheet.getCell(colArray[i].letter + j).alignment = {horizontal: colArray[i].horizontal,};if (colArray[i].dataType === "date") {worksheet.getCell(colArray[i].letter + j).dataValidation = {type: "date",operator: "between",showErrorMessage: true,allowBlank: true,formulae: [new Date(1900, 1, 1), new Date(2100, 1, 1)],showInputMessage: true,promptTitle: "日期",prompt: "请输入日期格式数据",};} else if (colArray[i].dataType === "number") {worksheet.getCell(colArray[i].letter + j).dataValidation = {type: "decimal",allowBlank: true,showErrorMessage: true,showInputMessage: true,promptTitle: "数字",prompt: "请输入数字格式数据",};}}}workbook.xlsx.writeBuffer().then(function (buffer) {saveAs(new Blob([buffer], {type: "application/octet-stream",}),fileName);});},

三,导入并解析

 importExcel() {const self = this;// 数据表格导入const importFile = document.createElement("input");importFile.style.display = "none";importFile.type = "file";importFile.value = "";importFile.accept =".csv,.xlc,.xlm,.xls,.xlt, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel";importFile.onchange = function (event) {self.button_24importF(event, () => {// 此处生成了空方法体});};importFile.click();},button_24importF(event, callback) {const self = this;const file = event.currentTarget.files[0];let success = false;const startIndex = file.name.lastIndexOf(".");if (startIndex < 0) {self.$message("文件格式错误,请重新选择!");return;}const types = file.name.slice(startIndex + 1);const fileType = ["xlsx", "xlc", "xlm", "xls", "xlt"].some((item) => item === types);if (!fileType) {self.$message("文件格式错误,请重新选择!");return;}const Excel = require("exceljs");const fileReader = new FileReader();const dicts = [];const relates = [];fileReader.onload = function (ev) {const data = ev.target.result;const workbook = new Excel.Workbook();workbook.xlsx.load(data).then(function () {// const values = ['菜单id', '菜单编码', '菜单别名', '功能模块ID', '功能ID', '父菜单', '显示顺序', '是否是叶子节点', '创建时间'];// const prop = ['menuId', 'menuText', 'menuAlias', 'functionModuleId', 'functionId', 'parentId', 'seq', 'isLeaf', 'createTime'];const values = ["姓名","用户账户","性别","最大会话数","手机号","微信账号",];const prop = ["staffName","userAccount","sex","maxSessions","mobile","weChat",];function cellValueToDict(keys, row) {const data = {};row.eachCell(function (cell, colNumber) {let value = cell.value;if (cell.type === Excel.ValueType.Date) {value = new Date(value.valueOf() - 8 * 60 * 60 * 1000);}if (dicts.length !== 0) {const findIndex = dicts.findIndex(function (dictItem) {return dictItem.field === prop[colNumber - 1];});if (findIndex !== -1) {if (value.toString().includes(",")) {const valueArr = [];value.split(",").forEach(function (val) {const dictItem = dicts[findIndex].dict.find(function (dictItem) {return (val === dictItem.label &&dictItem.field === prop[colNumber - 1]);});if (dictItem) {valueArr.push(dictItem.value);} else {valueArr.push(value);}});value = valueArr.join(",");} else {const dictItem = dicts[findIndex].dict.find(function (dictItem) {return (value === dictItem.label &&dictItem.field === prop[colNumber - 1]);});if (dictItem) {value = dictItem.value;}}}}data[prop[colNumber - 1]] = value;});return data;}const dataArray = [];let keys = [];const worksheet = workbook.worksheets[0]; // 获取第一个worksheetworksheet.eachRow(function (row, rowNumber) {if (rowNumber === 1) {keys = row.values;} else if (rowNumber > 1) {const rowDict = cellValueToDict(keys, row);dataArray.push(rowDict);}});const valuesCopy = values.slice(0);const keysCopy = keys.filter(function (el) {return el;}).slice(0);if (JSON.stringify(keysCopy.sort()) !==JSON.stringify(valuesCopy.sort())) {HussarRouter.showMsg(self, "导入模板错误,请重新选择!", "error");return;}//处理时间格式问题开始dataArray.forEach(function (item) {for (let val in item) {if (item[val] instanceof Date) {item[val] = dateFormatPublic("datetime", item[val]);}}});/*** parentId 机构编号* parentName 机构名称* departmentId 所在机构*/dataArray.forEach((item) => {item.departmentId = self.currentNodeData.departmentId;item.parentId = self.currentNodeData.id;item.parentName = self.currentNodeData.label;});});};fileReader.readAsBinaryString(file);},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/651466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日一题 力扣2861 最大合金数

2861. 最大合金数 题目描述&#xff1a; 假设你是一家合金制造公司的老板&#xff0c;你的公司使用多种金属来制造合金。现在共有 n 种不同类型的金属可以使用&#xff0c;并且你可以使用 k 台机器来制造合金。每台机器都需要特定数量的每种金属来创建合金。 对于第 i 台机器…

华为机考入门python3--(0)模拟题3-计算字符串重新排列数

分类&#xff1a;排列组合 知识点&#xff1a; 计算字符串中每个字符出现的次数 Counter(string) 计算列表中每个元素出现的次数 Counter(list) 阶乘 math.factorial(num) 排列去重 题目来自【华为招聘模拟考试】 先把每个字符当成唯一出现过一次&#xff0c;计算所有排列…

keepalived+nginx双主热备(有问题私信)

keepalivednginx双主热备 前言keepalivednginx双主热备keepalivednginx双主热备部署安装nginx安装keepalived修改master节点的keepalived配置文件 修改backup节点的keeepalived配置文件配置keepalived主备配置keepalived双主热备 前言 有关keepalived和nginx的一些工作原理&am…

【论文笔记】《Learning Deconvolution Network for Semantic Segmentation》

重要说明&#xff1a;严格来说&#xff0c;论文所指的反卷积并不是真正的 deconvolution network 。 关于 deconvolution network 的详细介绍&#xff0c;请参考另一篇博客&#xff1a;什么是Deconvolutional Network&#xff1f; 一、参考资料 Learning Deconvolution Netwo…

一步步安装Ruby攻略

在大多数操作系统上安装Ruby的步骤基本相同。以下是安装Ruby的详细步骤&#xff1a; 对于Ubuntu或其他基于Debian的系统&#xff1a; 打开终端。输入以下命令更新软件包列表&#xff1a; sql复制代码 sudo apt update 安装Ruby&#xff1a; 复制代码 sudo apt install rub…

ROS2常用命令工具

ROS2常用命令工具 包管理工具ros2 pkg ros2 pkg create ros2 pkg create --build-type ament_python pkg_name rclpy std_msgs sensor_msgs –build-type : C或者C ament_cmake &#xff0c;Python ament_python pkg_name &#xff1a;创建功能包的名字 rclpy std_msgs sens…

【Leetcode】2861. 最大合金数

文章目录 题目思路代码结果 题目 题目链接 假设你是一家合金制造公司的老板&#xff0c;你的公司使用多种金属来制造合金。现在共有 n 种不同类型的金属可以使用&#xff0c;并且你可以使用 k 台机器来制造合金。每台机器都需要特定数量的每种金属来创建合金。 对于第 i 台…

【word visio绘图】关闭visio两线交叉的跳线(跨线)

【visio绘图】关闭visio两线交叉的跳线&#xff08;跨线&#xff09; 1 如何在Visio绘图中关闭visio两线交叉的跳线&#xff08;跨线&#xff09;第一步&#xff1a;打开Visio并创建您的图形第二步&#xff1a;绘制您的连接线第三步&#xff1a;关闭跳线第四步&#xff1a;手动…

centos,rocky安装部署guacamole

安装部署guacamole 部署的环境是 Rocky9.3 版本,部署的 guacamole 的版本是 1.5.4 一、Rocky下载对应的工具 安装对应的开发环境建议一条一条命令执行 sudo yum install epel-release -y sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro sudo rpm -Uvh …

dnSpy调试工具二次开发2-输出日志到控制台

本文在上一篇文章的基础上继续操作&#xff1a; dnSpy调试工具二次开发1-新增菜单-CSDN博客 经过阅读dnSpy的源码&#xff0c;发现dnSpy使用到的依赖注入用了MEF框架&#xff0c;所以在源码中可以看到接口服务类的上面都打上了Export的特性或在构造方法上面打上ImportingConst…

C/C++ - 类的封装特性

目录 类的封装 语法格式 声明定义 分文件 访问权限 类作用域 对象模型 构造函数 默认构造函数 带参构造函数 拷贝构造函数 构造函数重载 委托构造函数 初始数据列表 构造默认参数 构造函数删除 析构函数 析构函数概念 析构函数特性 析构函数示例 析构调用…

坚持刷题 | 平衡二叉树

文章目录 题目考察点代码实现实现总结对实现进一步改进扩展提问 坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天继续二叉树&#xff1a;平衡二叉树 题目 110.平衡二叉树 考察点 递归能力&#xff1a; 能否使用递归来解决问题。树的基本操作&#xff1a;能否正确地访…

DS:带头双向循环链表的实现(超详细!!)

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01;&#xff01; 博主的上篇文章介绍了链表&#xff0c;以及单链表的实现。 单链表的实现&#xff08;超详细&#xff01;&#xff01;&#xff09; 其实单链表的全称叫做不带头单向不循环链表&#xff0c;本文…

zabbix使用自动发现批量监控服务器

当有大量新增服务器需要监控时&#xff0c;为避免一台一台手动操作浪费人力&#xff0c;我们使用自动发现功能来进行操作&#xff1a; 以下以zabbix6.4.0版本为例 如下,点击自动发现&#xff0c;创建发现规则&#xff1a; 点击更新&#xff0c;保存&#xff0c;之后点告警---…

ubuntu 22.04 安装redis并设置远程连接

ubuntu 22.04 安装redis并设置远程连接 1、基础安装 更新包&#xff1a; sudo apt update安装redis&#xff1a; sudo apt install redis-server安装完毕后会自动启动&#xff0c;查看状态&#xff1a; sudo systemctl status redis-server注意&#xff1a;如果你的服务器上仅用…

在 React 组件中使用 JSON 数据文件,怎么去读取请求数据呢?

要在 React 组件中使用 JSON 数据&#xff0c;有多种方法。 常用的有以下几种方法&#xff1a; 1、直接将 JSON 数据作为一个变量或常量引入组件中。 import jsonData from ./data.json;function MyComponent() {return (<div><h1>{jsonData.title}</h1>&…

node.js Redis SETNX命令实现分布式锁解决超卖/定时任务重复执行问题

Redis SETNX 特性 当然&#xff0c;让我们通过一个简单的例子&#xff0c;使用 Redis CLI&#xff08;命令行界面&#xff09;来模拟获取锁和释放锁的过程。 在此示例中&#xff0c;我将使用键“lock:tcaccount_[pk]”和“status:tcaccount_[pk]”分别表示锁定键和状态键。 获…

AAC解码算法原理

关于更多音视频开发内容&#xff0c;请参考专栏音视频开发 AAC&#xff08;Advanced Audio Coding&#xff09;是一种高级音频编码标准&#xff0c;它是一种十分流行的音频压缩格式&#xff0c;通常用于存储和传输音频数据。AAC提供了高音质和高压缩效率&#xff0c;广泛应用于…

Android源码设计模式解析与实战第2版笔记(四)

第三章 自由扩展你的项目–Builder 模式 Builder 模式的定义 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 Builder 模式的使用场景 相同的方法&#xff0c;不同的执行顺序&#xff0c;产生不同的事件结果时 多个部件或零件&…

Android 基础技术——Handler

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 Handler 为什么一个线程对应一个Looper&#xff1f; 核心&#xff1a;通过ThreadLocal保证 Looper.prepare的时候&#xff0c;ThreadLocal.get如果不空报异常&#xff1b;否则调用ThreadLocal.set,…