赞
踩
过程:
后台(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); },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。