element-ui + vue + nodejs 的多文件(表格)导入与下载

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();// 直接写会调用三次接口
            },
        }

就像这样,至于下载、导出之后文件要不要删除,怎么删除,我还没有弄,加油,骚年们

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值