elementui之封装下载模板和导入文件组件方式
牛先森家的牛奶 人气:0elementui封装下载模板和上传组件
封装代码如下
<template> <div> <el-dialog :title="exportStatus? '导入结果' : '一键导入数据'" :visible.sync="dialogVisible" width="905px" :before-close="handleClose" class="export-standard-speech" > <div class="standard-export" v-if="!exportStatus"> <div class="export-title">1、下载导入模板</div> <div class="export-warning">根据提示完善表格内容</div> <div class="export-download-btn"> <img src="@/assets/img/download-demo-icon.png" width="12px" style=" vertical-align: baseline; margin-right: 3px; margin-top:2px; display: inline-block; " /> <a class="a-line" :href="downloadDemoUrl" rel="external nofollow" download="项目导入模板.xlsx" title="下载空的表格模板" >下载空的表格模板</a> </div> <div class="export-title">2、上传完善后的表格</div> <el-upload class="upload-demo-xls" drag ref="speechDemoUpload" action="" :file-list="fileList" :auto-upload="false" :show-file-list="false" accept=".xls,.xlsx,.csv" :on-change="handleChange" > <div class="el-upload__text" v-if="!uploadStatus">将文件拖到此处,或点击<em>上传</em></div> <div class="el-upload__text" v-else> <span class="file-name">{{ this.file && this.file.name }}</span> <span class="file-size">({{bytesToSize(this.file.size)}})</span> <span class="file-select">重新选择</span> </div> </el-upload> <div class="h32 flex-center-center" style="margin-top:38px"> <Button text="取消" background="#fff" border="#4646E6" color="#4646E6" class="ml10" @click.native="cancelExport" ></Button> <Button text="导入" background="#4646E6" color="#fff" class="ml10" @click.native="xlsDemoExport" :setGray="isFile"></Button> </div> </div> <div v-if="exportStatus && failNum > 0"> <div class="fail-num"> <img src="@/assets/img/export-fail-img.png" alt="" class="mr10"> 导入失败 <span>{{failNum}}条</span> 数据 </div> <div class="export-fail-table"> <div class="export-fail-text">以下为导入失败的项目,您可修改后重新导入</div> <el-table :data="tableData" height="220" > <el-table-column prop="lineNum" label="Execel行数" width="220" align="left" > </el-table-column> <el-table-column prop="projectCode" label="项目编号" width="220" align="center" > </el-table-column> <el-table-column prop="failReason" label="失败原因" width="220" align="right" > </el-table-column> </el-table> </div> <div class="h32 flex-center-center" style="margin-top:23px"> <Button text="关闭" background="#fff" border="#4646E6" color="#4646E6" @click.native="cancelExport" ></Button> </div> </div> <div v-if="exportStatus && failNum == 0"> <div class="success-img"> <img src="@/assets/img/export-success-img.png" alt="" class="mr10"> </div> <div class="success-text"> 成功导入 <span>{{ successNum }}条</span> 数据 </div> <div class="h32 flex-center-center" style="margin-top:23px"> <Button text="完成" background="#4646E6" color="#fff" class="" @click.native="cancelExport"></Button> </div> </div> </el-dialog> </div> </template> <script> import Button from "@/components/Button"; import { upload, service } from '@/utils/request-brand' import { bytesToSize } from '@/utils' export default { name: 'ImportData', components: { Button }, props: { showDialogVisible: { type: Boolean, default: false, required: true }, downloadDemoUrl:{ type: String, required: true }, uploadFileUrl:{ type: String, required: true }, // 考虑上传时其他参数的情况 otherUploadData:{ type: Object, default:() => { return {} } } }, computed: { userAccountID() { return this.$store.state.user.userAccountID; }, isFile(){ if(this.file){ return false } else { return true } } }, watch: { showDialogVisible(newVal) { // console.log(newVal); this.dialogVisible = newVal } }, data () { return { dialogVisible: false, fileList: [], file: null, // 上传文件的状态切换 uploadStatus: false, successNum: 0, failNum: 0, tableData: [], // 导入的状态 exportStatus: false, }; }, methods: { bytesToSize, handleClose(done) { this.dialogVisible = false this.$emit('dialogVisible', false) }, // 取消或者清空上传的文件和数据 cancelExport(){ // this.$refs.speechDemoUpload.clearFiles() this.fileList = [] this.file = null this.successNum = 0 this.failNum = 0 this.tableData = [] this.uploadStatus = false this.exportStatus = false this.$emit('dialogVisible', false) }, // 上传的文件改变时(覆盖原来的文件) handleChange(file, fileList){ // console.log(file); let extension = file.raw.name.substring(file.raw.name.lastIndexOf(".") + 1); let size = file.size / 1024 / 1024; // let size = file.size / 1024; // console.log(extension, extension.toLowerCase() !== "xlsx"); if (!['xlsx','xls','csv'].includes(extension.toLowerCase())) { this.$message.warning("文件格式不正确,请上传xls / xlsx / csv格式"); return false; } if (size > 10) { this.$message.warning("文件过大,请进行拆分后分多次上传"); return false } // console.log(file.raw, fileList); if (fileList.length > 0) { this.fileList = [fileList[fileList.length - 1]] // 这一步,是展示最后一次选择的csv文件 this.file = this.fileList[0].raw } // console.log(this.file); this.uploadStatus = true }, async xlsDemoExport(){ if (!this.file) { // return this.$message.error('请上传文件') return false } const formData = new FormData() formData.append('file', this.file) // 添加其他参数 if(Object.values(this.otherUploadData).length > 0){ for (let key in this.otherUploadData) { formData.append(key, this.otherUploadData[key]) } } // 调用上传接口... this.$loading.show() // `${process.env.VUE_APP_BASE_BRAND_API}/v1/inspectionSpeechArt/importExcel upload.uploadFile(this.uploadFileUrl, formData).then(res => { if(res.code == 0){ this.exportStatus = true this.tableData = res.item.failList.map(item => { let obj = {} obj.lineNum = item.lineNum obj.failReason = item .failReason obj.projectCode = item. projectCode return obj }) this.failNum = res.item.failNum this.successNum = res.item.successNum } else { this.$message.error(res.message) } this.$loading.hide() }).catch((error) => { console.log(error); this.$message.error('上传失败,请稍后再试或联系IT解决') this.$loading.hide() }) }, }, } </script> <style lang="scss" scoped> ::v-deep .el-dialog{ width: 25%; border-radius: 12px; margin-top:-8vh !important; top: 50%; transform: translateY(-50%); } ::v-deep .el-dialog__header { border-bottom: 1px solid #efeff6; padding-left: 50px; .el-dialog__title, .el-dialog__headerbtn i { color: #36395c !important; font-size: 18px !important; font-weight: 600; } } </style> <style lang="scss"> .export-standard-speech { .el-list-enter-active, .el-list-leave-active { transition: none; } .el-list-enter, .el-list-leave-active { opacity: 0; } .el-upload-list { height: 40px; } // 表格body .el-dialog__body{ padding: 30px 100px; } // 导入 .standard-export{ .upload-demo-xls{ width: 100%; margin-top: 20px; } .el-upload.el-upload--text{ width: 100%; } .el-upload-dragger{ width: 100%; display: flex; justify-content: center; align-items: center; border: 1px solid #EFEFF6; height: 120px; .el-upload__text{ font-weight: 600; color: #36395C; .file-name{ color: #4646E6; } .file-size{ color: #CCCDD8; } .file-select{ color: #4646E6; text-decoration: underline; } } } .export-title{ font-size: 14px; color: #36395C; font-weight: 600; line-height: 20px; } .export-warning{ font-size: 14px; color: #CCCDD8; line-height: 20px; } .export-download-btn{ width: 165px; height: 36px; border: 1px solid #4646E6; color: #4646E6; opacity: 1; border-radius: 6px; display: flex; align-items: center; justify-content: center; margin: 20px 0 30px; } } // 导入失败的表格数据 .fail-num{ display: flex; justify-content: center; align-items: center; margin-bottom: 24px; font-size: 16px; color: #36395C; font-weight: 600; span{ color: #EF6E49; margin: 0 3px; } } .export-fail-table{ width: 100%; height: 280px; border: 1px solid #EFEFF6; border-radius: 6px; padding: 0 20px; .export-fail-text{ font-size: 14px; line-height: 20px; color: #36395C; font-weight: 600; margin-bottom: 20px; margin-top: 20px; } .el-table__row { height: 60px; td { padding: 0 30px; } } .has-gutter tr { height: 60px; } .has-gutter tr th { font-size: 14px; color: #333333; font-family: Arial; padding: 0 20px; } thead th { font-size: 14px; color: #333333; font-weight: 600; height: 40px; background: #F5F6FB; } // 滚动条的宽度 .el-table__body-wrapper::-webkit-scrollbar { width: 6px; // 横向滚动条 height: 6px; // 纵向滚动条 } // 滚动条的滑块 .el-table__body-wrapper::-webkit-scrollbar-thumb { background-color: #E2E2E2; border-radius: 3px; } } .success-img{ display: flex; justify-content: center; align-items: center; margin-top: 103px; } .success-text{ display: flex; justify-content: center; align-items: center; margin-top: 30px; margin-bottom: 50px; font-size: 16px; color: #36395C; font-weight: 600; span{ color: #4646E6; margin: 0 3px; } } } </style>
页面使用
只上传文件的形式
<template> <div class="upload"> <Button text="批量导入" background="#36395C" color="#fff" :icon="true" @click.native="handleExportBtn" /> // ... <ImportData :showDialogVisible="exportVisible" :downloadDemoUrl="downloadStandardSpeech" :uploadFileUrl="uploadFileUrl" @dialogVisible="closeVisible" /> </div> </template> <script> import ImportData from '@/views/components/ImportData.vue' export default { name: "index", components: { ImportData, }, data() { return { // 导入弹框显示和隐藏 exportVisible: false, downloadStandardSpeech: `${process.env.VUE_APP_EXPORTDEOM_API}/fileResources/templates_standardSpeech.xlsx`, // 模板下载文件地址, uploadFileUrl: 'http://10.0.0.10:3000/v1/inspectionSpeechArt/importExcel' // 可以写在配置文件中 }; }, computed: { userAccountID() { return this.$store.state.user.userAccountID; }, }, // created() { // this.getDataList(); // this.getCheckType(); // }, activated() { this.getDataList(); this.getCheckType(); }, watch:{}, methods: { // 导入 handleExportBtn(){ this.exportVisible = true }, // 关闭导入 closeVisible(){ this.exportVisible = false // 刷新列表等操作 }, }, }; </script> <style lang="scss" scoped> </style>
上传文件和其他必传参数的形式
<template> <div class="upload"> <Button text="批量导入" background="#36395C" color="#fff" :icon="true" @click.native="handleExportBtn" /> // ... <ImportData :showDialogVisible="exportVisible" :downloadDemoUrl="downloadStandardSpeech" :uploadFileUrl="uploadFileUrl" :otherUploadData="otherUploadData" @dialogVisible="closeVisible" /> </div> </template> <script> import ImportData from '@/views/components/ImportData.vue' export default { name: "index", components: { ImportData, }, data() { return { // 导入弹框显示和隐藏 exportVisible: false, downloadStandardSpeech: `${process.env.VUE_APP_EXPORTDEOM_API}/fileResources/templates_standardSpeech.xlsx`, // 模板下载文件地址, uploadFileUrl: 'http://10.0.0.10:3000/v1/inspectionSpeechArt/importExcel', otherUploadData: {}, }; }, computed: { userAccountID() { return this.$store.state.user.userAccountID; }, }, // created() { // this.getDataList(); // this.getCheckType(); // this.otherUploadData = { key : 'value' }; // }, activated() { this.getDataList(); this.getCheckType(); this.otherUploadData = { key : 'value' }; }, watch:{}, methods: { // 导入 handleExportBtn(){ this.exportVisible = true }, // 关闭导入 closeVisible(){ this.exportVisible = false // 刷新列表等操作 }, }, }; </script> <style lang="scss" scoped> </style>
效果如下
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
加载全部内容