过程:
后台(go)+ 中间(node - express)+前端(vue)
使用node进行中间层转发,前端使用form-data进行数据上传,传递给node,node使用form-data将数据传给后端(go),成功后将文件在oss进行备份
前端上传excel

页面效果:
在这里插入图片描述
1.页面布局实现:(使用elementui框架)

<el-upload
  class="upload-demo"
  ref="fileupload"
  accept=".xls,.xlsx"    // 接受上传文件类型
  action="##"              //  上传地址,由于上传文件成功还需执行其他,所以写##
  :before-upload="beforeUpload"  //  上传文件之前的钩子
  :http-request="uploadSectionFile"   // 覆盖默认的上传行为,可自定义上传实现
  drag  // 是否启动拖拽上传
  v-loading='uploadFlag'>
  <i class="el-icon-upload"></i>
  <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  <div class="el-upload__tip" slot="tip">只能上传xlsx文件</div>
</el-upload>

2.上传之前校验文件内容是否符合要求,使用js-xlsx解析文件,下面以判断文件中日期是否一致为例

如未安装js-xslx,需先安装

npm install xlsx

接下来在页面中引入

import XLSX from 'xlsx';

在校验文件中调用XLSX

beforeUpload(file) {
  const that = this;
  // 使返回的值变成Promise对象,如果校验不通过,则reject,校验通过,则resolve
  return new Promise((resolve, reject) => {
    // readExcel方法也使用了Promise异步转同步,此处使用then对返回值进行处理
    that.readExcel(file).then((result) => { // 此时标识校验成功,为resolve返回
      if (result) {
        resolve('校验成功!');
      } else {
        that.$message.error('请检查文件内容日期是否一致');
      }
    }, (error) => { // 此时为校验失败,为reject返回
      that.$message.error(error);
    });
  });
},
// 解析Excel,查看文件中的日期是否一致
readExcel(file) { 
  return new Promise((resolve, reject) => { // 返回Promise对象
    const reader = new FileReader();
    let data,
      workbook;
    reader.onload = (e) => { // 异步执行
      try {
        // 以二进制流方式读取得到整份excel表格对象
        data = e.target.result;
        workbook = XLSX.read(data, { type: 'binary' });
      } catch (ev) {
        reject(ev.message);
      }

      // 表格的表格范围,判断第一列内容是否正确
      // 遍历每张表读取
      if (workbook.Sheets.length > 1) {
        resolve(false);
      } else {
        for (const sheet in workbook.Sheets) {
          if (Object.prototype.hasOwnProperty.call(workbook.Sheets, sheet)) {
            const sheetInfos = workbook.Sheets[sheet];
            let locations = '';
            for (const key in sheetInfos) {
              if (Object.prototype.hasOwnProperty.call(sheetInfos, key)) {
                const reg = /[A]/g;
                if (reg.test(key) && key !== 'A1') {
                  if (locations === '') {
                    locations = sheetInfos[key].w;
                  } else if (locations !== sheetInfos[key].w) {
                    resolve(false);
                  }
                }
              }
            }
            const newlocations = locations.split('/');
            let month,
              day;
            if (newlocations[0] < 10) {
              month = `0${newlocations[0]}`;
            } else {
              month = newlocations[0];
            }
            if (newlocations[1] < 10) {
              day = `0${newlocations[1]}`;
            } else {
              day = newlocations[1];
            }
            const nowDate = `20${newlocations[2]}-${month}-${day}`;
            this.Evalue = nowDate;
            this.Svalue = nowDate;
          }
        }
        resolve(true);
      }
    };
    reader.readAsBinaryString(file);
  });
},

3.前端上传文件到node

uploadSectionFile(item) {
  const form = new FormData();
  // 文件对象
  form.append('file', item.file);
  this.$axios({
    method: 'post',
    url: "node请求地址"
    data: form,
  }).then((res) => {
     // 写自己的代码逻辑
  });
},

4.node接收到的参数req.files如下

{ file:
   { fieldName: 'file',
     originalFilename: 'xxxxxx.xlsx',
     path:
      '/var/folders/k9/jc7jb8w91yqb2w85rkppsj8m0000gn/T/4mDO8jEdeVixVNV11RcVAcS_.xlsx',
     headers:
      { 'content-disposition':
         'form-data; name="file"; filename="xxxxxx.xlsx"',
        'content-type':
         'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
     size: 13360,
     name: 'xxxxxx.xlsx',
     type:
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
 }

需要将req.files中的file参数用from-data传递给后端(go)

使用form-data创建可读的“ multipart / form-data”流的模块。

安装form-data模块

npm install  form-data
const FormData = require('form-data')
const fs = require('fs');
const path = require('path');

const { path: filePath, originalFilename } = req.files.file
const newPath = path.join(path.dirname(filePath), originalFilename) // 得到newPath新地址用于创建读取流
const user_name = req.body.username;
fs.rename(filePath, newPath, (err) => {
  if (err) {
    return;
  } else {
    const file = fs.createReadStream(newPath) //创建读取流
    const form = new FormData() // new formdata实例
    form.append('upload', file) // 把文件加入到formdata实例中
    request({
      method: 'post',
      url:'后端接口',
      body:form,
      headers: form.getHeaders()  //formdata的headers
    },function(error, response, body) {
      if (!error && response.statusCode == 200) {
          res.send(body)
      } else{
        res.send(error)
      }
    })
  }
})

5.成功后在oss进行文件备份

upload(item) {
  const client = new OSS({
      region: 'Your bucket name', //比如:oss-cn-beijing
      accessKeyId: 'Your accessKeyId',
      accessKeySecret: 'Your accessKeySecret',
      bucket: 'Your bucket name',
    }),
    object = item.file.name;  //上传文件名称
  client.put(object, item.file).then((r1) => {
    if (r1) {
      this.$message.success('上传成功');
    }
  }).then((r2) => {
    if (r2) {
      this.$message.success('上传成功');
    }
  }).catch((err) => {
    this.$message.error(err);
  });
},

如果oss中文件已存在,则添加编号(0 -100)比如xxxx1.xslx

/*
 * 判断oss中文件是否存在
 * client oss配置信息
 * object 文件名称
 * item 要上传的文件
 */
fileTest(client, object, item) {
  client.get(object).then((result) => {
    if (result.res.status === 200) {
      this.modifyFileName(client, object, item);
    }
  }).catch((e) => {
    if (e.code === 'NoSuchKey') {
      client.put(object, item.file).then((r1) => {
        if (r1) {
          this.upload(item);
        }
      }).then((r2) => {
        if (r2) {
          this.upload(item);
        }
      }).catch((err) => {
        this.$message.error(err);
      });
    }
  });
},
/*
* 修改上传文件名称
*/
modifyFileName(client, object, item) {
  const newObject = object.split('.'),
    reg = /^\d*$/;
  let num = newObject[0][newObject[0].length - 1];
  if (reg.test(num)) {
    const newNum = newObject[0].substring(newObject[0].length - 2);
    if (reg.test(newNum)) {
      num = Number(newNum);
    } else {
      num = Number(num);
    }
    num += 1;
  } else {
    num = 1;
  }
  const name = item.file.name.split('.'),
    newName = `${name[0]}${window.localStorage.getItem('username')}${num}.${newObject[1]}`;
  this.fileTest(client, newName, item);
},

Logo

前往低代码交流专区

更多推荐