vue3 + antd vue 纯前端 基于xlsx 实现导入excel 转 json,将json数据转换XLSX并下载(下载模版)

一、导入

0、关键代码

// 安装插件
npm i xlsx/yarn add xlsx
// 导入xlsx
import * as XLSX from 'xlsx';

点击提交的时候才整理数据。上传的时候文件保存在  state.form.file[0] 中的

// 定义字段映射关系
const fieldMap = {sheet2json: {技能名称: 'skill_name',技能等级: 'skill_level',技能描述: 'skill_desc',技能类型: 'skill_type',技能效果: 'skill_effect',技能消耗: 'skill_cost',技能持续时间: 'skill_duration',技能范围: 'skill_range',技能范围: 'skill_range',技能目标: 'skill_target'}
};// 提交 --- 点击提交的时候才整理数据。上传的时候文件保存的  state.form.file[0] 中的
const handleSummit = () => {formRef.value.validate().then(async () => {try {const data = await state.form.file[0].arrayBuffer(); // 使用 arrayBuffer 避免中文乱码const workbook = XLSX.read(data, { type: 'buffer' });const outdata = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);// 映射字段名并过滤掉不符合预期的数据const mappedData = outdata.map(row => {return Object.keys(row).reduce((targetMap, key) => {const mappedKey = fieldMap.sheet2json[key];if (mappedKey) {targetMap[mappedKey] = row[key];}return targetMap;}, {});}).filter(item => Object.keys(item).length > 0); // 过滤空对象console.log('------- 导入的数据 -------', mappedData);emits('submit', mappedData);handleClose();} catch (error) {}});
};

1、template

<a-form :model="state.form" name="form" ref="formRef" :label-col="{ style: { width: '120px' } }" autocomplete="off" :rules="rules"><a-form-item label="导入文件上传" name="file" :rules="rules.file"><div class="file-warp" style="position: relative"><a-uploadstyle="margin-left: 20px":file-list="state.form.file"name="file":customRequest="upload":beforeUpload="beforeUpload"@remove="handleRemove"accept=".xlsx, .xls"><a-button type="primary"><upload-outlined></upload-outlined>上传文件</a-button></a-upload><a-button type="primary" ghost style="position: absolute; top: 0; left: 150px" @click="handleDownload"><VerticalAlignBottomOutlined></VerticalAlignBottomOutlined>模版下载</a-button></div></a-form-item>
</a-form>

2、script

import * as XLSX from 'xlsx';
import { reactive, ref } from 'vue';const state = reactive({form: {file: []}
});
const formRef = ref(null);
const open = ref(true);const rules = {file: [{ required: true, message: '请选择文件', trigger: ['blur', 'change'] }]
};// 定义字段映射关系
const fieldMap = {sheet2json: {技能名称: 'skill_name',技能等级: 'skill_level',技能描述: 'skill_desc',技能类型: 'skill_type',技能效果: 'skill_effect',技能消耗: 'skill_cost',技能持续时间: 'skill_duration',技能范围: 'skill_range',技能范围: 'skill_range',技能目标: 'skill_target'},json2sheet: {skill_name: '技能名称',skill_level: '技能等级',skill_desc: '技能描述',skill_type: '技能类型',skill_effect: '技能效果',skill_cost: '技能消耗',skill_duration: '技能持续时间',skill_range: '技能范围',skill_target: '技能目标'}
};// 上传文件之前检测
const beforeUpload = file => {const isXlsxOrXls = file.name.split('.')[1] == 'xlsx' || file.name.split('.')[1] == 'xls';if (!isXlsxOrXls) {message.error('只允许上传xlsx, xls格式的文件!');return false;}const isLt10M = file.size / 1024 / 1024 < 10;if (!isLt10M) {message.error('文件不得大于10MB!');return false;}return isXlsxOrXls && isLt10M;
};// 选择文件
const upload = file => {// 原本调用接口上传的// uplaodFile(file.file).then(res => {//   fileList.value.push({ name: res.data.originalFilename, url: viteConfig.baseUrl + res.data.fileName, fileUrl: res.data.fileName });//   formRef.value.clearValidate();// });state.form.file = [file.file];formRef.value.clearValidate();
};// 移除文件
const handleRemove = file => {state.form.file = [];
};// 提交 转换数据
const handleSummit = () => {formRef.value.validate().then(async () => {try {const data = await state.form.file[0].arrayBuffer(); // 使用 arrayBuffer 避免中文乱码const workbook = XLSX.read(data, { type: 'buffer' });const outdata = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);// 映射字段名并过滤掉不符合预期的数据const mappedData = outdata.map(row => {return Object.keys(row).reduce((targetMap, key) => {const mappedKey = fieldMap.sheet2json[key];if (mappedKey) {targetMap[mappedKey] = row[key];}return targetMap;}, {});}).filter(item => Object.keys(item).length > 0); // 过滤空对象console.log('------- 导入的数据 -------', mappedData);emits('submit', mappedData);handleClose();} catch (error) {}});
};

二、模板下载

1、script

// 定义字段映射关系
const fieldMap = {json2sheet: {skill_name: '技能名称',skill_level: '技能等级',skill_desc: '技能描述',skill_type: '技能类型',skill_effect: '技能效果',skill_cost: '技能消耗',skill_duration: '技能持续时间',skill_range: '技能范围',skill_target: '技能目标'}
};// 模板数据
let templateData = [{skill_name: '大刀斩',skill_level: '5',skill_desc: '技能描述',skill_type: '大招',skill_effect: '亚瑟王那样的大招',skill_cost: '10000',skill_duration: '10',skill_range: '500',skill_target: '目标:亚瑟王'}
];// 模版下载
const handleDownload = () => {// 映射字段名并过滤掉不符合预期的数据const list = templateData.map(row => {return Object.keys(row).reduce((targetMap, key) => {const mappedKey = fieldMap.json2sheet[key];if (mappedKey) {targetMap[mappedKey] = row[key];}return targetMap;}, {});}).filter(item => Object.keys(item).length > 0); // 过滤空对象;const workSheet = XLSX.utils.json_to_sheet(list);const workBook = XLSX.utils.book_new();XLSX.utils.book_append_sheet(workBook, workSheet, '技能表');// 生成Excel文件并下载XLSX.writeFile(workBook, '技能表模板.xlsx');
};

三、完整的文件

<!--* @Description: ------------ fileDescription -----------* @Author: snows_l snows_l@163.com* @Date: 2024-07-18 14:46:47* @LastEditors: snows_l snows_l@163.com* @LastEditTime: 2024-07-19 15:51:19* @FilePath: /digital-qiankun-you/cmdb/src/pages/ipSource/components/uploadFile.vue
-->
<template><div class="upeate-field-warp"><a-modal width="800px" v-model:open="open" :z-index="10004" centered :title="'规划导入'"><template #footer><a-button type="primary" @click="handleSummit">确认</a-button></template><div class="update-field-content-warp"><a-form :model="state.form" name="form" ref="formRef" :label-col="{ style: { width: '120px' } }" autocomplete="off" :rules="rules"><a-form-item label="导入文件上传" name="file" :rules="rules.file"><div class="file-warp" style="position: relative"><a-uploadstyle="margin-left: 20px":file-list="state.form.file"name="file":customRequest="upload":beforeUpload="beforeUpload"@remove="handleRemove"accept=".xlsx, .xls"><a-button type="primary"><upload-outlined></upload-outlined>上传文件</a-button></a-upload><a-button type="primary" ghost style="position: absolute; top: 0; left: 150px" @click="handleDownload"><VerticalAlignBottomOutlined></VerticalAlignBottomOutlined>模版下载</a-button></div></a-form-item></a-form></div></a-modal></div>
</template><script setup>
import { UploadOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons-vue';
import { reactive, ref } from 'vue';
import * as XLSX from 'xlsx';const emits = defineEmits(['submit']);const state = reactive({form: {file: []}
});
const formRef = ref(null);
const open = ref(true);const rules = {file: [{ required: true, message: '请选择文件', trigger: ['blur', 'change'] }]
};// 上传文件之前检测
const beforeUpload = file => {const isXlsxOrXls = file.name.split('.')[1] == 'xlsx' || file.name.split('.')[1] == 'xls';if (!isXlsxOrXls) {message.error('只允许上传xlsx, xls格式的文件!');return false;}const isLt10M = file.size / 1024 / 1024 < 10;if (!isLt10M) {message.error('文件不得大于10MB!');return false;}return isXlsxOrXls && isLt10M;
};// 选择文件
const upload = file => {// 原本调用接口上传的// uplaodFile(file.file).then(res => {//   fileList.value.push({ name: res.data.originalFilename, url: viteConfig.baseUrl + res.data.fileName, fileUrl: res.data.fileName });//   formRef.value.clearValidate();// });state.form.file = [file.file];formRef.value.clearValidate();
};// 移除文件
const handleRemove = file => {state.form.file = [];
};// 初始化
const init = () => {open.value = true;
};// 关闭
const handleClose = () => {open.value = false;
};// 定义字段映射关系
const fieldMap = {sheet2json: {技能名称: 'skill_name',技能等级: 'skill_level',技能描述: 'skill_desc',技能类型: 'skill_type',技能效果: 'skill_effect',技能消耗: 'skill_cost',技能持续时间: 'skill_duration',技能范围: 'skill_range',技能范围: 'skill_range',技能目标: 'skill_target'},json2sheet: {skill_name: '技能名称',skill_level: '技能等级',skill_desc: '技能描述',skill_type: '技能类型',skill_effect: '技能效果',skill_cost: '技能消耗',skill_duration: '技能持续时间',skill_range: '技能范围',skill_target: '技能目标'}
};// 模板数据
let templateData = [{skill_name: '大刀斩',skill_level: '5',skill_desc: '技能描述',skill_type: '大招',skill_effect: '亚瑟王那样的大招',skill_cost: '10000',skill_duration: '10',skill_range: '500',skill_target: '目标:亚瑟王'}
];// 提交
const handleSummit = () => {formRef.value.validate().then(async () => {try {const data = await state.form.file[0].arrayBuffer(); // 使用 arrayBuffer 避免中文乱码const workbook = XLSX.read(data, { type: 'buffer' });const outdata = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);// 映射字段名并过滤掉不符合预期的数据const mappedData = outdata.map(row => {return Object.keys(row).reduce((targetMap, key) => {const mappedKey = fieldMap.sheet2json[key];if (mappedKey) {targetMap[mappedKey] = row[key];}return targetMap;}, {});}).filter(item => Object.keys(item).length > 0); // 过滤空对象console.log('------- 导入的数据 -------', mappedData);emits('submit', mappedData);handleClose();} catch (error) {}});
};// 模版下载
const handleDownload = () => {// 映射字段名并过滤掉不符合预期的数据const list = templateData.map(row => {return Object.keys(row).reduce((targetMap, key) => {const mappedKey = fieldMap.json2sheet[key];if (mappedKey) {targetMap[mappedKey] = row[key];}return targetMap;}, {});}).filter(item => Object.keys(item).length > 0); // 过滤空对象;const workSheet = XLSX.utils.json_to_sheet(list);const workBook = XLSX.utils.book_new();XLSX.utils.book_append_sheet(workBook, workSheet, '技能表');// 生成Excel文件并下载XLSX.writeFile(workBook, '技能表模板.xlsx');
};defineExpose({init
});
</script><style lang="less" scoped>
.upeate-field-warp {width: 100%;
}
</style><style lang="less">
.update-field-content-warp {padding: 40px 20px;.field-item {display: flex;align-items: center;label {min-width: 80px;}}
}
</style>

四、效果图:

原数据(图1)

导入组件(图2)

导出整理后的数据(图3)

模板下载(图4)

模板下载之后的文件(图5)

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

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

相关文章

uni-app 影视类小程序开发从零到一 | 开源项目分享

引言 在数字娱乐时代&#xff0c;移动设备已成为我们生活中不可或缺的一部分&#xff0c;尤其是对于电影爱好者而言&#xff0c;随时随地享受精彩影片成为一种日常需求。爱影家&#xff0c;一款基于 uni-app 开发的影视类小程序&#xff0c;正是为此而生。它不仅提供了丰富的影…

【Django+Vue3 线上教育平台项目实战】购物车与订单模块的精简实现与数据安全策略

文章目录 前言一、购物车模块1.后端核心逻辑2.前端页面代码3.操作流程及演示 二、订单模块1.订单模块模型类设计1.展示订单信息a.页面展示b.前端核心代码c.后端核心逻辑 2.订单是否使用优惠券与积分a.页面展示b.前端核心代码 3.订单支付方式a.页面展示b.前端核心代码 4.提交订单…

PyTorch Autograd内部实现

原文&#xff1a; 克補 爆炸篇 25s (youtube.com) 必应视频 (bing.com)https://www.bing.com/videos/riverview/relatedvideo?&qPyTorchautograd&qpvtPyTorchautograd&mid1B8AD76943EFADD541E01B8AD76943EFADD541E0&&FORMVRDGAR 前面只要有一个node的re…

北京交通大学《深度学习》专业课,实验3卷积、空洞卷积、残差神经网络实验

一、实验要求 1. 二维卷积实验&#xff08;平台课与专业课要求相同&#xff09; ⚫ 手写二维卷积的实现&#xff0c;并在至少一个数据集上进行实验&#xff0c;从训练时间、预测精 度、Loss变化等角度分析实验结果&#xff08;最好使用图表展示&#xff09; ⚫ 使用torch.nn…

Matlab基础语法篇(下)

Matlab基础语法&#xff08;下&#xff09; 一、逻辑基础&#xff08;一&#xff09;逻辑运算符&#xff08;二&#xff09;all、any、find函数&#xff08;三&#xff09;练习 二、结构基础&#xff08;一&#xff09;条件结构&#xff08;1&#xff09;if-elseif-else-end&am…

十、操作符详解

目录 1、操作符分类 2、二进制转换 2.1二进制转十进制 2.1.1、十进制转二进制 2.2、二进制转八进制和十六进制 2.2.1、二进制转八进制 2.2.2、二进制转十六进制 3、原码、反码、补码 4、移位操作符&#xff08;移动的是二进制位&#xff09; 4.1、左移操作符 4.2、右…

VMware虚拟机下安装Ubuntu(详细教程,最小系统的安装,含VMware Tools)

1.VM的下载安装 VMware的下载安装教程_vm16 pro下载-CSDN博客 2. Ubuntu 下载 在官网或者镜像站下载所需版本的.ios镜像&#xff0c;这个镜像在接下来的步骤中会用到&#xff1a; Ubuntu 22.04.4 LTS 下载 和 清华大学开源软件镜像站 - Ubuntu 22.04.4 下载 3. 创建虚拟机 […

【C语言】深入解析希尔排序

文章目录 什么是希尔排序&#xff1f;希尔排序的基本实现代码解释希尔排序的优化希尔排序的性能分析希尔排序的实际应用结论 在C语言编程中&#xff0c;希尔排序是一种高效的排序算法&#xff0c;是插入排序的一种更高效的改进版本。它通过比较相距一定间隔的元素来进行排序&am…

【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键

这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平&#xff0c;同时保持其它行为高电平&#xff0c;然后读取所有列的电平状态&#xff0c;可以检测到哪个按键被按下。如果某列变为低电平&#xff0c;说明对应行和列的按键被按下…

【Java】详解抽象类和接口的区别

一、抽象类和接口的主要区别表格 特性抽象类接口声明关键字abstractinterface声明访问修饰符public、protected、default&#xff08;不能用private&#xff09;public、default继承关键字extendsimplements变量跟普通类一样&#xff0c;可以包含实例变量、静态变量等 只能包含…

excel表怎么增乱序单词表 和正序单词表四六级要来了?!Excel帮你构建自己的单词库

excel表怎么增乱序单词表 和正序单词表四六级要来了&#xff1f;&#xff01;Excel帮你构建自己的单词库 1.背单词的第一步&#xff0c;当然是先上网找电子版的单词集。 盘搜搜 2. 建立 xls 格式的表格 3. 把下载的单词数据 复制到 表格 粘贴 4.新建一列 辅助列 生成随机数来…

网络编程-TCP/IP

网络概述 网络采用分而治之的方法设计&#xff0c;将网络的功能划分为不同的模块&#xff0c;以分层的形式有机组合在一起。 每层实现不同的功能&#xff0c;其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务&#xff0c;同时使用下层提供的服务 网络体系结构…

SpringMVC注解全解析:构建高效Web应用的终极指南 (上)

SpringMVC 是一个强大的 Web 框架&#xff0c;广泛应用于 Java Web 开发中。它通过注解简化了配置&#xff0c;增强了代码的可读性。本文将全面解析 SpringMVC 中常用的注解及其用法&#xff0c;帮助你构建高效的 Web 应用。 一. MVC介绍 MVC 是 Model View Controller 的缩写…

数字通云平台 智慧政务OA PayslipUser SQL注入漏洞复现

0x01 产品简介 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术,为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平,推动电子政务向更高层次发展。 0x02 漏洞概述 数字通云平台 智慧政务OA Paysli…

使用百度语音技术实现文字转语音

使用百度语音技术实现文字转语音 SpringBootVue前后端分离项目 调用api接口需要使用AK和SK生成AccessToken,生成getAccessToken的接口有跨域限制,所以统一的由后端处理了 部分参数在控制台->语音技术->在线调试里面能找到 Controller RestController RequestMapping(&q…

PostgreSQL的引号、数据类型转换和数据类型

一、单引号和双引号&#xff08;重要&#xff09;&#xff1a; 1、在mysql没啥区别 2、在pgsql中&#xff0c;实际字符串用单引号&#xff0c;双引号相当于mysql的,用来包含关键字&#xff1b; -- 单引号&#xff0c;表示user_name的字符串实际值 insert into t_user(user_nam…

浏览器跨tab页面通信方式总结

需求&#xff1a; 浏览器不同 tab 标签页之间是独立的&#xff0c; 如果要通信必须通过特殊手段来实现跨标签页通信。 1.StorageEvent 事件 当一个标签页 localStorage 变化时&#xff08;sessionStorage 无效&#xff09;&#xff0c;同源下另一个或其他所有标签页使用 DO…

python多级表头汇总

需求&#xff1a;将图一的数据展示为图二样式 图一&#xff1a; 图二&#xff1a; 图一具体的Excel截图 图二具体样式 python解决办法&#xff1a; # 导入 pandas 库&#xff0c;用于数据处理 import pandas as pd# 加载 Excel 文件 file_path 多级表头读取实例.xl…

科研绘图系列:R语言circos图(circos plot)

介绍 Circos图是一种数据可视化工具,它以圆形布局展示数据,通常用于显示数据之间的关系和模式。这种图表特别适合于展示分层数据或网络关系。Circos图的一些关键特点包括: 圆形布局:数据被组织在一个或多个同心圆中,每个圆可以代表不同的数据维度或层次。扇区:每个圆被划…

【BUG】已解决:SyntaxError invalid syntax

SyntaxError invalid syntax 目录 SyntaxError invalid syntax 【常见模块错误】 错误原因&#xff1a; 解决办法&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于…