JS实现Excel文件与图片视频上传
作者:DCodes
Excel上传
excel
的上传其实分为两步:
1、下载excel
模板
2、上传excel
模板
在项目中涉及到excel
的业务,基本上都要先下载excel
模板,用户根据下载的模板填写excel
信息,然后将信息上传到后台。下面就这两部分别说明:
1、下载excel
模板
关于下载excel
模板的内容请看:调用后台接口实现Excel导出功能以及导出乱码问题解决(点击直达)
2、上传excel
模板
这里用到element
的上传组件,element
上传组件提供点击上传和拖动文件上传。
<template> <div> <el-upload class="upload-demo" ref="upload" drag :data="uploadData" :action="actionUrl" :accept="acceptType" :headers="headers" :limit="fileLimit" :on-exceed="handleExceed" :file-list="fileList" :before-remove="beforeRemove" :on-progress="onProgress" :on-success="onSuccess" :on-error="onError" > <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> </el-upload> <div v-if="fileInfo"> <el-table :data="errorList" border style="width: 100%"> <el-table-column prop="fileName" label="失败文件" > </el-table-column> <el-table-column prop="error" label="失败原因"> </el-table-column> </el-table> </div> </div> </template> <script> import { getToken } from "@/utils/auth"; import { isArray } from "min-dash"; export default { name: "ExcelUpload", props: { uploadData: { type: Object, default: "", }, actionUrl: { type: String, default: "", }, acceptType: { type: String, default: "", }, }, components: {}, data() { return { fileLimit: 1, // 最大值 headers: {}, // 请求头 fileInfo: false, // 上传文件 errorList: [], // 错误列表 progress: { totalFileCount: 0, // 总文件 handleFileCount: 0, // 上传文件 }, fileList: [], // 上传展示的文件列表,如果fileLimit = 1,该数组只能有一个成员 }; }, created() { this.headers["Authorization"] = "Bearer " + getToken(); // 获取请求头信息 }, methods: { onSuccess(response, file, fileList) { if (response.code == 200) { if (Array.isArray(response.data)) { if (response.data.length > 0) { this.fileInfo = true; file.status = "error"; this.errorList = []; this.errorList.push(...response.data); this.$message.error(`操作失败`); } else { this.$emit("uploadBack"); } } else { this.$emit("uploadBack"); } } else { this.errorList = []; this.errorList.push({ fileName: '', error: response.msg }); this.fileInfo = true; file.status = "error"; this.$message.error(`${response.msg}`); } }, onError(err, file, fileList) { file.status = "error"; this.$message.error(`${err.msg}`); }, handleExceed(files, fileList) { this.$message.warning(`上传文件数超出限制`); }, onProgress(event, file, fileList) {}, beforeRemove(file, fileList) { this.$confirm("确定移出吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.fileList = []; this.fileInfo = false; this.errorFile = false; }) .catch(() => { fileList.push(file); }); }, }, mounted() {}, watch: {}, computed: {}, filters: {}, }; </script>
这里是将element
的上传组件进行二次封装,该组件的职责就是负责接受上传的文件、上传地址、上传类型,做通用化处理,在任何需要上传功能的页面引入即可使用,下面将组件拆开来讲:
<el-upload class="upload-demo" ref="upload" drag :data="uploadData" :action="actionUrl" :accept="acceptType" :headers="headers" :limit="fileLimit" :on-exceed="handleExceed" :file-list="fileList" :before-remove="beforeRemove" :on-progress="onProgress" :on-success="onSuccess" :on-error="onError" > <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> </el-upload>
:data
:element的上传组件允许我们在上传的时候携带上传参数,这里的 :data
就是上传携带的参数,该参数由父组件提供(主要业务),这样就可以在多种不同情况下使用,避免参数固定化。
:action
:请求地址,这个请求地址就是后台的接口,但是这个接口不能直接使用,需要在接口前加 process.env.VUE_APP_BASE_API
来判断当前的运行环境。
:acceptType
: 接受文件的类型,例如这里上传 .xlsx
文件,那么点击上传的时候,只会读取系统里 .xlsx 的文件。该类型也是由父页面提供,这样可以区分多种文件上传情况,该组件可以适配多种文件类型,例如:.jpg
、.png
、.xlsx
、.mp4
等。
:headers
:请求头,需要加上token
才能成功上传。
:limit="fileLimit" :on-exceed="handleExceed" :file-list="fileList" :before-remove="beforeRemove" :on-progress="onProgress" :on-success="onSuccess" :on-error="onError"
这些就是组件的一些事件以及属性,根据element
文档阅读即可,这里带一下:
limit
:最大上传文件数
on-exceed
:上传文件超出最大数时的钩子,可以做错误提示
file-list
:上传文件的数组
before-remove
:上前的事件
on-progress
: 上传中的事件,该事件在上传过程中会持续调用,可以用来做进度条展示。
on-success
:上传成功的事件,当接口返回200
,触发该事件。
on-error
: 上传失败的事件,当接口返回500
,触发该事件。
页面中的使用
<ExcelUploadList @uploadBack="uploadBack" :acceptType="acceptType" :actionUrl="actionUrl" :uploadData="uploadData" ></ExcelUploadList>
export default { props: { area: Object, allArea: Object, }, data() { return { acceptType: ".zip", // 上传文件类型 uploadData: {}, // 上传附加的参数信息 // 文件上传的接口 actionUrl: `${process.env.VUE_APP_BASE_API}/data/loadExcel/importZip`, }; }, methods: { uploadBack(response) { // 上传成功后触发事件 this.$message.success(`操作成功`); // this.getList(); 刷新列表 }, onImport() { if (!this.area.id) { return this.$message.warning("请选择地区"); } this.uploadData = { fiProvinceCode: this.allArea.fiProvinceCode, // 省 fiCityCode: this.allArea.fiCityCode, // 市 fiAreaCode: this.allArea.fiAreaCode, // 区 fiSubdistrictId: this.allArea.fiSubdistrictId, // 街道 fiCommunityId: this.allArea.fiCommunityId, // 社区 }; }, }, created() {}, activated() {}, components: { ExcelUpload, }, };
通过父组件将自身业务所需的参数传入到上传组件中,具体的上传业务由组件完成,完成后将结果返回给父组件展示或者刷新展示列表。
图片和视频
上文中上传excel
的组件,其实已经可以用作图片和视频上传了,我们只需要传入对应的图片或视频接口 actionUrl
,然后将对应的上传类型 acceptType:'.mp4'
提供给组件,在选择文件时就只读取.mp4
的文件,然后将上传所需的参数 uploadData
提供给组件,那么图片和视频上传就已经完成了。
上传图片和视频并不需要模板,直接上传即可,所以会比较方便。其实上传文件都是将文件转成file
文件或者formData
,将文件传给后端即可。
// file转formData function files(file){ let formData = new FormData(); formData.append("file", file); // file转formData //formData参数传给后端 ossUpload(formData).then(res=>{ //.... }) }
如果你要在formData
上追加参数,只需要:
let formData = new FormData(); formData.append("file", file); // file转formData formData.append("params1", val1); formData.append("params2", val2); // ....... //formData参数传给后端 ossUpload(formData).then(res=>{ //.... })
上传的错误提醒以及逻辑处理
某些情况下,我们需要对上传文件做逻辑处理,比如上传失败该如何处理、上传成功如何处理、能上传几个文件、将上传文件的列表做删除、上传中的进度处理等,这些逻辑,组件都提供了对应的钩子,如下:
created() { this.headers["Authorization"] = "Bearer " + getToken(); }, methods: { // 上传成功的钩子,某些情况下需要做逻辑处理 // 上传5个文件,成功3个,失败2个,这个时候需要在这里做上传失败的文件展示 onSuccess(response, file, fileList) { if (response.code == 200) { // 如果失败列表为数组证明有上传失败 if (Array.isArray(response.data)) { // 上传失败列表数大于0表示有失败文件 if (response.data.length > 0) { this.fileInfo = true; // 打开错误列表展示弹窗 file.status = "error"; // 更改类型,关联css的字体变红 this.errorList = []; this.errorList.push(...response.data); // 错误列表数据 this.$message.error(`操作失败`); } else { // 如果错误列表为空,则表示全部上传成功 this.$emit("uploadBack"); } } else { // 全部上传成功 this.$emit("uploadBack"); } } else { // 上传失败 this.errorList = []; // 错误列表数据 this.errorList.push({ fileName: '', error: response.msg }); this.fileInfo = true; // 打开错误列表展示弹窗 file.status = "error"; // 更改类型,关联css的字体变红 this.$message.error(`${response.msg}`); } }, // 上传失败的钩子 onError(err, file, fileList) { file.status = "error"; // 更改类型,关联css的字体变红 this.$message.error(`${err.msg}`); }, // 上传文件数超出限制的钩子 handleExceed(files, fileList) { this.$message.warning(`上传文件数超出限制`); }, // 进度条钩子 onProgress(event, file, fileList) {}, // 点击移出上传文件的钩子 beforeRemove(file, fileList) { this.$confirm("确定移出吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { // 重置上传文件的列表,这里限制最大上传为 1 ,所以移出就直接重置 this.fileList = []; this.fileInfo = false; // 关闭上传失败的信息弹窗 this.errorFile = false; // 关闭错误信息弹窗 }) .catch(() => { fileList.push(file); // 取消则将文件重新添加到列表,不做任何更改。 }); }, },
上传失败,在文件展示这里将字体变为红色
<style lang='scss' scoped> ::v-deep .el-upload-list__item.is-error { .el-upload-list__item-name { color: #ff4949 !important; } } </style>
上传进度处理
element
上传组件帮我们关联了上传进度,从发送请求到请求发送成功,其实这个过程只是将file
文件转formData
请求接口的过程,真实的文件处理进度并不能通过自带的进度条直接展示,需要调用后端的接口获取上传进度,遍历后端提供的上传进度接口,使用定时器,每隔一段时间调用一次,获取最新的上传进度,当上传进度为100%
时停止定时器。
// 上传文件成功的钩子 onSuccess(response, file, fileList) { if (response.code == 200) { this.fileInfo = true; // 上传进度处理,定时器循环调用 let times = setInterval(() => { tailProgressAPI(this.uploadData).then((res) => { // handleFileCount 已处理数量 // totalFileCount 上传总数 // 错误文件数大于0,更新错误列表 if (res.data.uploadFailList.length > 0) { this.errorList = []; this.errorFile = true; this.errorList.push(...res.data.uploadFailList); } // 处理数 = 上传总数 处理完成 if (res.data.handleFileCount == res.data.totalFileCount) { // 页面展示处理结果 this.progress.totalFileCount = res.data.totalFileCount; this.progress.handleFileCount = res.data.handleFileCount; // 回传上传结果 this.$emit("uploadBack", { code: 200, msg: "操作成功" }); // 停止定时器 clearInterval(times); } else { // 处理中 // 更新处理结果 this.progress.totalFileCount = res.data.totalFileCount; this.progress.handleFileCount = res.data.handleFileCount; } }); }, 500); } else { file.status = "error"; // 更改类型,关联css的字体变红 this.$message.error(`${response.msg}`); // 提示错误信息 } },
以上就是JS实现Excel文件与图片视频上传的详细内容,更多关于JS文件上传的资料请关注脚本之家其它相关文章!