有这么一个需求:一个导入按钮,点击按钮导入excel表,如果excel表中部分数据导入失败,则自动下载该部分导入失败数据的excel表,如果全部导入成功,则提示“导入成功”。
首先附上ElementUI的上传文件组件
Element - The world's most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN/component/upload官网详细介绍upload组件的属性和使用方法,就不展开了,这里主要通过使用它实现开篇的导入excel表的需求。(在vue项目中需要引入ElementUI库,详细步骤请查阅官网)
1、引入ElementUI上传组件upload
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
multiple
:auto-upload="false"
:file-list="fileList"
:on-change="fileChange">
<el-button type="primary">导入</el-button>
</el-upload>
页面效果
属性介绍
属性、说明、类型
auto-upload | 是否在选取文件后立即进行上传 | boolean |
auto-upload我们设置为false,避免自动上传,以便使用自定义上传方式。?
file-list | 上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}] | array |
on-change | 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 | function(file, fileList) |
2、点击导入按钮,选择文件(点击“打开”触发on-change)
此时可以通过fileChange方法在控制台打印查看文件结构
fileChange(file,fileList){
console.log(file,'file')
console.log(fileList,'fileList')
}
3、此时我们已经拿到选择的文件,可以自定义上传方式,将其发送至后端服务器
fileChange(file,fileList){
console.log(file,'file')
console.log(fileList,'fileList')
let url = 'xxx' //后端服务器API
let headers = {
'Content-Type':'multipart/form-data' //自定义上传时,该请求头参数必填
}
let formData = ''
for(let i = 0;i < fileList.length;i++){ //遍历文件数组,fileList有可能存在多个文件
formData = new FormData()
formData.append('name',fileList[i].name)
formData.append('type','.xlsx')
formData.append('file',fileList[i].raw)
}
this.$axios({
headers: headers,
method: 'post',
data: formData,
url: url,
responseType:'blob' //该参数必填,不然下载下来的excel表会提示文件损坏,无法打开
}).then(res=>{
if(res && res.data.size == 0){
//若后台不返回流,说明全部数据导入成功,提示“导入成功”,不自动下载
return
}
//如果后台返回流,说明部分数据导入失败,则自动下载导入失败数据的excel表
let name = '导入失败数据.xlsx' //自定义下载excel表名
let blob = new Blob([res.data])
let url = window.URL.createObjectURL(blob)
let aLink = document.createElement('a')
aLink.style.display = 'none'
aLink.href = url
//download 属性定义了下载链接的地址。href 属性必须在 <a> 标签中指定。
aLink.setAttribute('download',name)
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink)
window.URL.revokeObjectURL(url)
//下载结束之后可以执行其他操作,如刷新列表、友好提示等
})
}
方法解析
formData是ajax2.0(XMLHttpRequest Level2)新提出的接口,利用FormData对象可以将form表单元素的name与value进行组合,实现表单数据的序列化,从而进行表单元素的拼接,提高工作效率。append?向FormData 中添加新的属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值。
Blob ?对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成?ReadableStream?来用于数据操作。?
URL.createObjectURL() ?静态方法会创建一个?DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的?document?绑定。这个新的URL 对象表示指定的?File?对象或?Blob?对象。
URL.revokeObjectURL() ?静态方法用来释放一个之前已经存在的、通过调用?URL.createObjectURL()?创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。
总结:以上实现了自定义导入excel表,且自动下载接口返回的流,代码可以直接使用,但是请注意返回的数据response不一定与我的相同,具体看联调接口的返回数据。
|