node mySql 实现数据的导入导出,以及导入批量插入的sql语句

node 实现导出, 在导出excel中包含图片(附件)

node 实现导出, 在导出excel中包含图片(附件)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/snows_l/article/details/139999392?spm=1001.2014.3001.5502

一、效果

如图:

二、导入

        1、前端上传文件

        2、后端 node 需要使用到 multer 中间件 将文件上传到服务器,然后使用 exceljs 这个插件进行文件的解析文件,代码如下:

/*** @description: 上传技能* @param {Object} req 请求对象* @param {Object} res 响应对象* @param {Function} next*/
// 配置 multer 存储
const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, '../public/common');},filename: function (req, file, cb) {cb(null, 'skill_' + file.originalname);}
});
const upload = multer({ storage: storage });
// 导入技能
router.post('/skill/import/:append', upload.single('file'), (req, res) => {const workbook = new Excel.Workbook();const filePath = req.file.path;// 读取文件workbook.xlsx.readFile(filePath).then(async () => {const worksheet = workbook.getWorksheet(1);// data 为解析文件得到的数据const data = [];worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {if (rowNumber === 1) return; // 跳过表头const rowData = row.values.slice(1); // 去掉第一列的索引data.push(rowData);});...})});

        3、最后拿到数据进行数据的批量插入

批量插入的sql语句如下 

 // 处理sql语句
let sql = 'INSERT INTO skill (name, level, description, type, effect, cost, duration, ranges, target) VALUES ?';
// data为解析到的数据
const params = data.map(item => [item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7], item[8]]);// 使用的时候
db.queryAsync(sql, [params]).then(result => {res.send({code: 200,data: data,msg: '导入成功'});}).catch(err => {console.log(err);res.send({code: 500,data: null,msg: '导入失败'});});

        特别注意的是,插入一条的时候 sql 语句  values 后面紧跟的 () , 然后 () 中的参数个数以及参数要与前面的key一一对应, 

当批量插入的时候: values 后面紧跟的是 [] , 然后数组 [] 中在是如同插入一条数据那样用 () , 一样 ()  中的参数个数以及参数要与前面的key一一对应, 数组 [] 多少个子项就插入多少条数据

        1)、eg1:插入一条数据sql:

        key与value一一对应 values 后紧跟()

let sql = 'INSERT INTO skill (name, level, description, type, effect, cost, duration, ranges, target) VALUES ('亚瑟王', '1', '老亚瑟', '1', '100', '200', '1s', '500', '周围敌人');';
        2)、eg1:插入3条(批量)数据sql:

        key与value一一对应 values 后紧跟[(), (), ()]

let sql = 'INSERT INTO skill (name, level, description, type, effect, cost, duration, ranges, target) VALUES [('亚瑟王1', '1', '老亚瑟', '1', '100', '200', '1s', '500', '周围敌人'), ('亚瑟王', '1', '老亚瑟2', '1', '100', '200', '1s', '500', '周围敌人'), ('亚瑟王3', '1', '老亚瑟', '1', '100', '200', '1s', '500', '周围敌人')];';

三、导出

导出就简单了 也是利用 exceljs 进行数据写入,直接上代码

router.post('/skill/export', (req, res) => {const { template } = req.body;const sql = 'SELECT * FROM skill';db.queryAsync(sql).then(async result => {const data = result.results;const workbook = new Excel.Workbook();const worksheet = workbook.addWorksheet('收入明细');// 设置表头// worksheet.addRow(['标题', '月份', '收入金额', '备注', '收入截图']);let baseTableTitle = [{ header: '技能名称', key: 'name', width: 12 },{ header: '技能等级', key: 'level', width: 10 },{ header: '技能描述', key: 'description', width: 20 },{ header: '技能类型', key: 'type', width: 12 },{ header: '技能效果', key: 'effect', width: 18 },{ header: '技能消耗', key: 'cost', width: 18 },{ header: '技能持续时间', key: 'duration', width: 20 },{ header: '技能范围', key: 'ranges', width: 20 },{ header: '技能目标', key: 'target', width: 20 }];worksheet.columns = baseTableTitle;// 如果不是模板,循环写入数据if (!template) {data.forEach(async (item, index) => {const rowData = worksheet.addRow([item.name, item.level, item.description, item.type, item.effect, item.cost, item.duration, item.ranges, item.target]);// 指定行高rowData.height = 50;});} else {// 如果下载模版 写入一条格式数据const rowData = worksheet.addRow(['大刀斩', '5', '技能描述', '大招', '亚瑟王那样的大招', '10000', '10', '500', '目标:亚瑟王']);// 指定行高rowData.height = 50;}const buffer = await workbook.xlsx.writeBuffer();// 处理中文文件名const realName = encodeURI('技能报表.xlsx', 'GBK').toString('iso8859-1');// 设置响应头res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');res.setHeader('Content-Disposition', 'attachment; filename=' + realName);// 发送Excel文件res.send(buffer);}).catch(err => {console.log(err);res.send({code: 500,msg: 'failed'});});
});

四、完整代码(整个文件)

/** @Description: ------------ fileDescription -----------* @Author: snows_l snows_l@163.com* @Date: 2024-06-26 10:20:25* @LastEditors: snows_l snows_l@163.com* @LastEditTime: 2024-06-26 18:06:52* @FilePath: /Website/Server/src/router/skill.js*/
const express = require('express');
const db = require('../../utils/connDB');
const Excel = require('exceljs');
const multer = require('multer');const router = express.Router();// 获取技能列表
router.get('/skill/list', (req, res) => {const { page = 1, size = 20, name, level } = req.query;let offset = (page - 1) * size;let sql = 'SELECT * FROM skill';let lenSql = `SELECT count('id') FROM skill`;if (name) {sql += ` WHERE name LIKE '%${name}%'`;lenSql += ` WHERE name LIKE '%${name}%'`;}if (level) {sql += ` ${name ? 'AND' : 'WHERE'} level = ${level}`;lenSql += ` ${name ? 'AND' : 'WHERE'} level = ${level}`;}sql += ` ORDER BY id ASC LIMIT ${size} OFFSET ${offset};`;db.queryAsync(lenSql).then(lenRes => {db.queryAsync(sql).then(result => {res.send({code: 200,data: result.results,total: lenRes.results[0]["count('id')"],msg: 'success'});}).catch(err => {console.log(err);res.send({code: 500,data: null,total: 0,msg: '系统异常, 请联系管理员'});});});
});// 导出技能
router.post('/skill/export', (req, res) => {const { template } = req.body;const sql = 'SELECT * FROM skill';db.queryAsync(sql).then(async result => {const data = result.results;const workbook = new Excel.Workbook();const worksheet = workbook.addWorksheet('收入明细');// 设置表头// worksheet.addRow(['标题', '月份', '收入金额', '备注', '收入截图']);let baseTableTitle = [{ header: '技能名称', key: 'name', width: 12 },{ header: '技能等级', key: 'level', width: 10 },{ header: '技能描述', key: 'description', width: 20 },{ header: '技能类型', key: 'type', width: 12 },{ header: '技能效果', key: 'effect', width: 18 },{ header: '技能消耗', key: 'cost', width: 18 },{ header: '技能持续时间', key: 'duration', width: 20 },{ header: '技能范围', key: 'ranges', width: 20 },{ header: '技能目标', key: 'target', width: 20 }];worksheet.columns = baseTableTitle;// 循环写入数据 如果不是模板,则默认写入数据if (!template) {data.forEach(async (item, index) => {const rowData = worksheet.addRow([item.name, item.level, item.description, item.type, item.effect, item.cost, item.duration, item.ranges, item.target]);// 指定行高rowData.height = 50;});} else {const rowData = worksheet.addRow(['大刀斩', '5', '技能描述', '大招', '亚瑟王那样的大招', '10000', '10', '500', '目标:亚瑟王']);// 指定行高rowData.height = 50;}const buffer = await workbook.xlsx.writeBuffer();// 处理中文文件名const realName = encodeURI('技能报表.xlsx', 'GBK').toString('iso8859-1');// 设置响应头res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');res.setHeader('Content-Disposition', 'attachment; filename=' + realName);// 发送Excel文件res.send(buffer);}).catch(err => {console.log(err);res.send({code: 500,msg: 'failed'});});
});/*** @description: 上传技能* @param {Object} req 请求对象* @param {Object} res 响应对象* @param {Function} next 中间件函数*/
// 配置 multer 存储
const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, '../public/common');},filename: function (req, file, cb) {cb(null, 'skill_' + file.originalname);}
});
const upload = multer({ storage: storage });
// 导入技能
router.post('/skill/import/:append', upload.single('file'), (req, res) => {const { append } = req.params;// 下一步function next(params) {const workbook = new Excel.Workbook();const filePath = req.file.path;// 读取文件workbook.xlsx.readFile(filePath).then(async () => {const worksheet = workbook.getWorksheet(1);const data = [];worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {if (rowNumber === 1) return; // 跳过表头const rowData = row.values.slice(1); // 去掉第一列的索引data.push(rowData);});// 处理sql语句let sql = 'INSERT INTO skill (name, level, description, type, effect, cost, duration, ranges, target) VALUES ?';const params = data.map(item => [item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7], item[8]]);db.queryAsync(sql, [params]).then(result => {res.send({code: 200,data: data,msg: '导入成功'});}).catch(err => {console.log(err);res.send({code: 500,data: null,msg: '导入失败'});});}).catch(err => {console.log(err);res.send({code: 500,data: null,msg: '导入失败'});});}// 判断是否是追加导入if (append == 2) {let cleanSql = 'TRUNCATE TABLE skill;';db.queryAsync(cleanSql).then(() => {next();});} else {next();}
});module.exports = router;

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

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

相关文章

声场合成新方法:基于声波传播的框架

声场合成是指在房间内的麦克风阵列上,根据来自房间内其他位置的声源信号,合成每个麦克风的音频信号。它是评估语音/音频通信设备性能指标的关键任务,因为它是一种成本效益高的方法,用于数据生成以替代真实的数据收集,后…

elasticsearch的安装和配置

单节点安装与部署 我们通过docker进行安装 1.docker的安装 如果以及安装了docker就可以跳过这个步骤。 首先更新yum: yum update安装docker: yum install docker查看docker的版本: docker -v此时我们的docker就安装成功了。 2.创建网络 我们还需要部署kiban…

盲源信道分离—FastICA算法性能仿真

本案例中使用Matlab软件对FastICA算法的声音分离性能进行了仿真,分别对简单波形的混合信号、不同类型声音的混合信号、同一类型的混合信号这三种情况进行仿真,主要从分离信号的波形形状、串音误差两方面对分离性能进行衡量,仿真结果显示快速I…

可以一键生成热点营销视频的工具,建议收藏

在当今的商业环境中,热点营销已经成为了一种非常重要的营销策略。那么,什么是热点营销呢?又怎么做热点营销视频呢? 最近高考成绩慢慢公布了,领导让结合“高考成绩公布”这个热点,做一个关于企业或产品的营销…

3.任务的创建与删除

1.什么是任务? 任务可以理解为进程/线程,创建一个任务,就会在内存开辟一个空间。 任务通常都含有while(1)死循环 2.任务创建与删除相关的函数 3.CUBEMAX相关配置 编辑一个led1闪烁的任务

RPC架构基本结构和核心技术

当你在构建一个分布式系统时,势必需要考虑的一个问题是:如何实现服务与服务之间高效调用?当然,你可以使用Dubbo或Spring Cloud等分布式服务框架来完成这个目标,这些框架帮助我们封装了技术实现的复杂性。那么&#xff…

Gitlab合并代码并解决冲突演示

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

Jenkins定时构建自动化(二):Jenkins的定时构建

目录 ​编辑 一、 jenkins定时构建语法: 1. 语法规则: 2. 常见用法举例 3. 再次举例 接上一篇:Jenkins定时构建自动化(一):Jenkins下载安装配置:Jenkins定时构建自动化(一):Jenkins下载安装配置-CSDN博客 …

input()函数——输入

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 input()函数可以提示并接收用户的输入,将所有的输入按照字符串进行处理,并返回一个字符串,input()函数的…

化茧成蝶 | 继HuggingFace首家落地大模型具身智能场景

关于具身智能的起源 近年来,大语言模型(LLMs)的兴起给机器人领域带来了革命性的改变,大模型赋予了传统机器人理解和推理的能力,让具身智能这一概念再度出现在大众的视角中。OpenCSG 作为国内 AI 开源社区的先锋&#…

python flask 入门-helloworld

学习视频链接: 01-【前奏】课程介绍_哔哩哔哩_bilibili 1.安装flask pip install flask 踩坑记:本机不要连代理,否则无法install 提示报错valueError: check_hostname requires server_hostname 2.程序编写 在根目录下创建 app.py fr…

从零开始学docker(四)-安装mysql及主从配置(一)

mysql MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关…

【HDC.2024】华为云Astro低代码平台开启AI敏捷组装时代,探索低代码创新无限可能

6月22日,华为开发者大会2024期间,华为云举办了以“敏捷组装时代来临「高低零码智能协同」加速行业创新”为主题的Astro低代码平台专题论坛。论坛汇聚了业界精英和专家学者,共同探讨低代码技术在推动企业数字化转型中的重要实践及未来发展趋势…

cs与msf权限传递,与mimikatz抓取win2012明文密码

CS与MSF的权限互相传递抓取windows2012的明文密码 CS与MSF的权限互相传递 1、启动cs服务端 2、客户端连接 3、配置监听,并设置监听端口为9999 4、生成脚本 5、开启服务,下载并运行木马 已获取权限 6、进入msf并设置监听 7、cs新建监听,与m…

【Linux】UDP协议

目录 传输层端口号netstat端口号范围划分认识知名端口号(Well-Know Port Number) UDP协议UDP协议端格式UDP的特点UDP的缓冲区UDP使用注意事项基于UDP的应用层协议 传输层 通过前面文章对于应用层的讲解,我们知道应用层主要是将我们的数据按照协议的格式进行划分&am…

注册安全分析报告:PingPong

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 …

Day15 —— 大语言模型简介

大语言模型简介 大语言模型基本概述什么是大语言模型主要应用领域大语言模型的关键技术大语言模型的应用场景 NLP什么是NLPNLP的主要研究方向word2vecword2vec介绍word2vec的两种模型 全连接神经网络神经网络结构神经网络的激活函数解决神经网络过拟合问题的方法前向传播与反向…

【Linux】锁|死锁|生产者消费者模型

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ ​ 访问互斥 …

力扣-两数之和

文章目录 题目题解方法1-暴力方法2-哈希 题目 原题链接:两数之和 题解 方法1-暴力 我最先想到的方法就是暴力,两层for循环,也能通过。(拿到算法题在没有思路的时候暴力就是思路,哈哈哈) public class T…

【STM32-存储器映射】

STM32-存储器映射 ■ STM32F1-4G地址空间分成8个块■ STM32F1-Block0■ STM32F1-Block1■ STM32F1-Block2■ STM32F1- ■ STM32F1-4G地址空间分成8个块 ■ STM32F1-Block0 有出厂 BootLoader 就可以使用串口下载程序。如Keil5图中IROM地址是0x8000000 开始 就是flash地址 ■ S…