1、安装
1.1 nodejs需安装
express、multer、mysql、xlsx(一般npm i XXX安装即可)
1.2 vue安装
npm i axios
2、下载
2.1 nodejs配置
(1)创建连接数据库的公开文件(常叫做 db.js)
let mysql = require("mysql");
// 公开数据
module.exports = {
// 键值对的方法
config: {
host: 'localhost', // 数据库在哪里?ip, 127.0.0.1,localhost
port: '3306', // 端口
user: 'root', // 用户名
password: '本机密码,一般测试用(root、123等)', // 密码
database: 'member',//数据库的名称
multipleStatements: "true", // true,允许同时执行多条SQL语句
},
// 将后面的函数赋值给connect,因为是键值对,所以可以写成 connect(){……}
connect(sql, params, cb) {
let conn = mysql.createConnection(this.config) //this指向调用connect方法得对象
conn.connect(); // 打开数据库的连接
conn.query(sql, params, cb); // 执行数据库
conn.end(); // 关闭数据库
}
}
(2)调用db.js
参考CSDN博主「swimxu」的原创文章,他的解释更全 https://blog.csdn.net/qq_53931766/article/details/127508230
const express = require("express"); // 引用express
const router = express.Router(); // 参加路由对象;
let db = require("../config/db"); // 数据库
var XLSX = require("xlsx"); // exel文档的转化库
// 下载所有会员信息
router.route("/download").post((req, res) => {
let sql = "SELECT * from member";
let params = [];
let cb = (err, data) => {
const body = data.map((x) => [
x.uname,
x.usex,
]);
// 表头信息
const header = [
["用户名"],
["性别"],
];
// console.log("header + ----------" + header);
// console.log("body===================" + body);
// 将定义好的表头添加到body中
body.unshift(header);
console.log(body);
// 创建虚拟表单
const workbook = XLSX.utils.book_new();
// 将二维数组转成 sheet(表)
// aoa_to_sheet 是将【一个二维数组】转化成 sheet
// json_to_sheet 是将【由对象组成的数组】转化成sheet
// table_to_sheet 是将【table的dom】直接转成sheet
const sheet = XLSX.utils.aoa_to_sheet(body);
// 需要时进行表格合并 + 行列高度
// 向 workbook 中添加 sheet
XLSX.utils.book_append_sheet(workbook, sheet, "单个表的名称");
// XLSX.utils.book_append_sheet(workbook, sheet2, '第二个表的名称');
// 导出文档
// 注意:定义导出 excel 的名称时需要加上后缀 .xlsx
try {
XLSX.writeFile(workbook, "./public/所有会员信息.xlsx");
res.json({
code: 200,
msg: "下载成功",
data: "所有会员信息.xlsx",
});
} catch (error) {
res.json({
code: 0,
msg: "下载个寂寞",
data: error,
});
}
};
db.connect(sql, params, cb);
});
module.exports = router; // 公开js文件中要暴露的对象模块
2.2前端配置
(1)直接下(法一)
// 这个地址是后端给的
<a href="http://localhost:8080/uploads/a.png(绝对地址)" download="a.png">文件下载</a>
(2)使用接口(法二)
<el-button size="small" @click="download">下载</el-button>
<script>
export default {
methods:{
download() {
axios({
url:'/api/download',
method:'post',
}).then(({ data }) => {
// 创建一个a标签
let a = document.createElement('a');
// 给a标签拼接地址
a.href = 'http://localhost:8888/' + data.data;
// 给a标签赋予download属性
a.download = '所有会员信息';
// 插入a标签
document.body.appendChild(a);
a.click();
// 点击后移除a标签
document.body.removeChild(a);
})
},
}
3 导入
3.1 nodejs 配置
(1)创建一个专门下载文件的文件夹并配置 uploadconfig.js
const multer = require('multer');
// 配置文件自动存储到硬盘
const storage = multer.diskStorage({
// 文件存储的目标位置
destination: function (req, file, cb) {
// 指定文件保存的路径
cb(null, "./public/upload"); // 必须先创建upload。
},
// 重命名上传的文件:
filename: function (req, file, cb) {
// 将下载的文件以数据流的形式转化成字符串
let newString = Buffer.from(file.originalname,"latin1").toString("utf8");
cb(null, newString)
},
});
const upload = multer({ storage: storage });
module.exports = upload;
(2)调用该文件
参考 js读取.xlsx Excel 文件内容,转成javascript可用数组数据 - 简书 (jianshu.com)
const express = require("express"); // 引用express
const router = express.Router(); // 参加路由对象;
let db = require("../config/db"); // 数据库
var XLSX = require("xlsx"); //
const upload = require("../config/uploadconfig");
router.route("/upload").post(upload.array("file", 3), (req, res) => {
// console.log(req.files);
let json = []; // 存放多个表单文件
for (let i = 0; i < req.files.length; i++) {
json.push(XLSX.readFile(req.files[i].path));
}
var persons = []; // 存储获取到的数据
// 表格的表格范围,可用于判断表头是否数量是否正确
var fromTo = "";
// 遍历每一个exel文件
for (let i = 0; i < json.length; i++) {
// 遍历单个Exel文档的每张表读取
for (var sheet in json[i].Sheets) {
if (json[i].Sheets.hasOwnProperty(sheet)) {
fromTo = json[i].Sheets[sheet]["!ref"];
// console.log(fromTo); // 如A1:J2,从A1到J2的长度
persons = persons.concat(
XLSX.utils.sheet_to_json(json[i].Sheets[sheet])
);
// break; // 如果只取第一张表,就取消注释这行
}
}
}
//在控制台打印出来表格中的数据
// console.log(persons);
let sql = "insert into member values";
let params = [];
for (let i = 0; i < persons.length; i++) {
sql += "(NULL,?,?),";
params.push(persons[i]["用户名"]);
params.push(persons[i]["性别"]);
}
sql = sql.substring(0, sql.length - 1)+";";
let cb = (err, data) => {
if (err === null) {
res.json({
code: 200,
msg: "导入成功",
});
} else {
res.json({
code: 200,
msg: "导入失败",
data: "err",
});
}
};
db.connect(sql, params, cb);
});
module.exports = router; // 公开js文件中要暴露的对象模块。
3.2 前端配置
参考 2019-12-19 element-ui文件上传 一次请求上传多个文件 - 简书 (jianshu.com)
<!-- on-change:改变文件时调用,file, fileList两种方法 -->
<!-- auto-upload 选取后上传 -->
<!-- action="none" 1取消上传时的接口访问,我们自定义上传 -->
<el-upload ref="upload" style="width: 100%;" class="upload-demo" drag action="/api/upload"
:on-change="handleChange" :auto-upload="false" :file-list="fileList" multiple :on-remove="fileRemove">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip" style="margin-left: 10%;">
请上传exel文档(格式为 XLS、XLSX、XLSB、XLSM、XLST),最多3个文件,最大为300KB
</div>
</el-upload>
<el-button type="primary" @click="okAddMember">确 定</el-button>
<script>
export default {
data() {
return {
fileList: [],
}
},
methods:{
// 选择exel文件
handleChange(file, fileList) {
if (fileList.length > 3) {
fileList.pop()
this.$message.error('最多只能传3个文件')
return
}
// 判断文件格式 XLS、XLSX、XLSB、XLSM、XLST
let reg = /^(XLS|XLSX|XLSB|XLSM|XLST)$/;
let index = file.name.lastIndexOf('.') // 找到最后一个点的下标
if (!reg.test(file.name.slice(index + 1).toUpperCase())) {
fileList.pop()
this.$message.error('请传入 XLS、XLSX、XLSB、XLSM、XLST 的exel文档格式')
return;
}
// 判断文件大小
if (file.sie > 1024 * 300) {
fileList.pop()
this.$message.error('请传入 300KB 以内的exel文档格式')
return;
}
this.fileList = fileList
},
// 删去某个文件(file删除的文件,fileList删除后,剩下的文件)
fileRemove(fileList) {
this.fileList = fileList;
},
// 确认上传文件
okAddMember() {
let formData = new FormData()
// console.log(this.fileList)
this.fileList.forEach(el => {
formData.append('file', el.raw)
})
axios({
url: "/api/upload",
method: "post",
data:formData,
}).then((res) => {
console.log(res);
if (res.data.code === 200) {
this.$refs.upload.clearFiles()
this.getTable()
this.dialogVisibleMembersmber = false
this.$message.success('导入成功')
} else {
this.$refs.upload.clearFiles()
this.$message.error('导入失败,请按导出的格式上传文件!!!')
}
})
// this.$refs.upload.submit();// 直接写会调用三次接口
},
}
就像这样,至于下载、导出之后文件要不要删除,怎么删除,我还没有弄,加油,骚年们