Excel下载模板文件和导入文件的步骤

avatar
作者
猴君
阅读量:0

一、配置api

// 题目导入模板下载接口 export function exportTemplate() {   return request({     url: '/edu/question/exportTemplate',     method: 'get',     //必加     header: {       headers: {         'Content-Type': 'application/x-download'       },     },     responseType: "blob",//必加   }) } // 题目模板数据导入接口 export function importTemplate(file) {   const data = new FormData()//必加   data.append('file', file)//必加   return request({     url: '/edu/question/import',     method: 'post',     data   }) }

二、vue中引用Api

import {   exportTemplate,   importTemplate, } from "@/api/edu/question"; 

三、引用下载文件的方法

//引用下载文件的方法 import { download } from "@/utils/excel";
方法:/utils/excel
/**  * 通用js方法封装处理  * Copyright (c) 2019  */  /**  * 参数处理  * @param {*} params  参数  */  // 封装exceljs import ExcelJS from 'exceljs' import FileSaver from 'file-saver'  export function tansParams(params) {   let result = ''   for (const propName of Object.keys(params)) {     const value = params[propName]     let part = `${encodeURIComponent(propName)}=`     if (value !== null && value !== '' && typeof value !== 'undefined') {       if (typeof value === 'object') {         for (const key of Object.keys(value)) {           if (             value[key] !== null &&             value[key] !== '' &&             typeof value[key] !== 'undefined'           ) {             let params = `${propName}[${key}]`             let subPart = `${encodeURIComponent(params)}=`             result += `${subPart + encodeURIComponent(value[key])}&`           }         }       } else {         result += `${part + encodeURIComponent(value)}&`       }     }   }   return result }  // 验证是否为blob格式 export function blobValidate(data) {   return data.type !== 'application/json' }  // export function getSrc(url) { //   return `https://${url}` // }  // 得到字典某个值的内容 export function getDictLabel(dict, value) {   let res = dict.filter((item) => item.value === value)   return res[0] }  // promise 只执行一次 export function oncePromise(fn, p = null) {   return function (...arg) {     // eslint-disable-next-line no-return-assign     return p || (p = fn(...arg).finally(() => (p = null)))   } }  /**  * 导出数据到Excel方法  * @param {Array[Object]} config.data 表格数据  * @param {Array[String]} config.fields 字段列表  * @param {Array[String]} config.headers excel表头列表[[]],可以是多级表头[['A1','B1'],['A2','B2']]  * @param {Array[Object]} config.merges 需要合并的单元格,需要考虑表头的行数[{row:1, col:1, rowspan: 1, colspan: 2}]  * @param {Array[Object]} config.attrs 单元格样式配置  * @param {Array[Object]} config.views 工作表视图配置  * @param {Array[Number]} columnsWidth 每个字段列对应的宽度  * @param {Object} config.protect 工作表保护【此配置会保护全表,一般推荐只针对单元格进行保护配置】  * @param {String} sheetName 工作表名称,默认从sheet1开始  * @param {String} fileName excel文件名称  */ export function exportDataToExcel(config, fileName) {   if (!config) return   const options = {     fileName: fileName || `导出excel文件【${Date.now()}】.xlsx`,     worksheets: [],   }   if (!Array.isArray(config)) {     config = [config]   }   config.forEach((item) => {     // 深拷贝data【JSON.stringify有缺陷,可自行换成_.cloneDeep】     const data = JSON.parse(JSON.stringify(item.data))     const results = data.map((obj) => item.fields.map((key) => obj[key])) // 生成完整excel数据     let excelData = []     excelData = excelData.concat(item.headers).concat(results) // 单元格合并处理【excel数据的第一行/列是从1开始】     let excelMerges = []     excelMerges = item.merges.map((m) => [       m.row + 1,       m.col + 1,       m.row + m.rowspan,       m.col + m.colspan,     ]) // 单元格配置处理【excel数据的第一行/列是从1开始】     let excelAttrs = []     excelAttrs = item.attrs.map((attr) => {       attr.rowStart += 1       attr.rowEnd += 1       attr.colStart += 1       attr.colEnd += 1       return attr     })     options.worksheets.push({       data: excelData,       merges: excelMerges,       attrs: excelAttrs,       views: item.views,       columnsWidth: item.columnsWidth,       protect: item.protect,       sheetName: item.sheetName,     })   })   createExcel(options) }  // 创建Excel文件方法 async function createExcel(options) {   if (!options.worksheets.length) return // 创建工作簿   const workbook = new ExcelJS.Workbook()   for (let i = 0; i < options.worksheets.length; i++) {     const sheetOption = options.worksheets[i] // 创建工作表     const sheet = workbook.addWorksheet(       sheetOption.sheetName || `sheet${i + 1}`     ) // 添加数据行     sheet.addRows(sheetOption.data) // 配置视图     sheet.views = sheetOption.views // 单元格合并处理【开始行,开始列,结束行,结束列】     if (sheetOption.merges) {       sheetOption.merges.forEach((item) => {         sheet.mergeCells(item)       })     } // 工作表保护     if (sheetOption.protect) {       const res = await sheet.protect(         sheetOption.protect.password,         sheetOption.protect.options       )     } // 单元格样式处理     if (sheetOption.attrs.length) {       sheetOption.attrs.forEach((item) => {         const attr = item.attr || {} // 获取开始行-结束行; 开始列-结束列         const { rowStart } = item         const { rowEnd } = item         const { colStart } = item         const { colEnd } = item         if (rowStart) {           // 设置行           for (let r = rowStart; r <= rowEnd; r++) {             // 获取当前行             const row = sheet.getRow(r)             if (colStart) {               // 列设置               for (let c = colStart; c <= colEnd; c++) {                 // 获取当前单元格                 const cell = row.getCell(c)                 Object.keys(attr).forEach((key) => {                   // 给当前单元格设置定义的样式                   cell[key] = attr[key]                 })               }             } else {               // 未设置列,整行设置【大纲级别】               Object.keys(attr).forEach((key) => {                 row[key] = attr[key]               })             }           }         } else if (colStart) {           // 未设置行,只设置了列           for (let c = colStart; c <= colEnd; c++) {             // 获取当前列,整列设置【大纲级别】             const column = sheet.getColumn(c)             Object.keys(attr).forEach((key) => {               column[key] = attr[key]             })           }         } else {           // 没有设置具体的行列,则为整表设置           Object.keys(attr).forEach((key) => {             sheet[key] = attr[key]           })         }       })     } // 列宽设置     if (sheetOption.columnsWidth) {       for (let j = 0; j < sheet.columns.length; j++) {         sheet.columns[j].width = sheetOption.columnsWidth[j]       }     }   } // 生成excel文件   workbook.xlsx.writeBuffer().then((buffer) => {     // application/octet-stream 二进制数据     FileSaver.saveAs(       new Blob([buffer], { type: 'application/octet-stream' }),       options.fileName     )   }) }  // 下载文件流文件 export const download = (res, type, filename) => {   // 创建blob对象,解析流数据   const blob = new Blob([res], {     // 设置返回的文件类型     // type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为'application/vnd.ms-excel'     type,   }) // 这里就是创建一个a标签,等下用来模拟点击事件   const a = document.createElement('a') // 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载   const URL = window.URL || window.webkitURL // 根据解析后的blob对象创建URL 对象   const href = URL.createObjectURL(blob) // 下载链接   a.href = href // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'   a.download = filename   document.body.appendChild(a) // 点击a标签,进行下载   a.click() // 收尾工作,在内存中移除URL 对象   document.body.removeChild(a)   window.URL.revokeObjectURL(href) } 

三、添加点击事件下载

HTML:

<template>   <!-- 导入对话框 -->   <el-dialog     :title="title"     :visible.sync="localImportShow"     width="600px"     @close="localImportClose"     append-to-body   >     <el-form ref="form" :model="form" :rules="rules" label-width="80px">       <el-row>         <el-col :span="24">           <el-form-item label="下载模板" prop="downloadTemplate">             <el-button type="primary" @click="downloadCClick">               下载               <i class="el-icon-download"></i>             </el-button>           </el-form-item>         </el-col>       </el-row>       <el-row>         <el-col :span="24">           <el-form-item label="导入数据" prop="file">             <el-upload               ref="uploadExcel"               class="upload-btn"               action="#"               :auto-upload="false"               accept=".xls, .xlsx"               :show-file-list="true"               :file-list="form.file"               :on-change="change"               :on-remove="handleRemove"               :limit="1"             >               <el-button slot="trigger" size="small" type="primary">                 选取文件               </el-button>             </el-upload>           </el-form-item>         </el-col>       </el-row>     </el-form>     <div slot="footer" class="dialog-footer">       <el-button type="primary" @click="submitForm">确 定</el-button>       <el-button @click="cancel">取 消</el-button>     </div>   </el-dialog> </template>

VUEJS:

<script> import { exportTemplate, importTemplate } from "@/api/edu/question"; import { download } from "@/utils/excel";  export default {   props: {     //弹出框是否展示     importShow: {       type: Boolean,       default: false,     },   },   data() {     return {       title: "导入试题数据",       form: {         file: [],       },       // 弹出框是否展示       localImportShow: this.importShow,       rules: {         file: [{ required: true, message: "请导入数据", trigger: "change" }],       },     };   },   watch: {     importShow(newVal) {       this.localImportShow = newVal;     },     "form.file": {       handler(nval) {         if (nval.length) {           this.$refs.form.clearValidate(["file"]);         }       },       deep: true,     },   },   methods: {     localImportClose() {       this.$emit("update:importShow", false);       this.reset();     },     // 点击下载模板按钮     downloadCClick() {       exportTemplate().then((res) => {         download(res, "application/vnd.ms-excel", "试题模板.xlsx");       });     },     // 更换上传文件     change({ raw }) {       //使用set watch才能监测到有值       this.$set(this.form.file, 0, raw);     },     handleRemove(file, fileList) {       // 移除上传文件       this.form.file = [];     },     // 提交事件     submitForm() {       this.$refs["form"].validate((valid) => {         if (valid) {           importTemplate(this.form.file[0])             .then((res) => {               if (res.code === 200) {                 this.localImportShow = false;                 this.$modal.msgSuccess("导入成功");                 this.$emit("getList");               }             })             .catch((err) => {               this.localImportShow = false;             });           this.$nextTick(() => {             this.reset();           });         }       });     },     // 取消按钮     cancel() {       this.localImportShow = false;       this.reset();     },     // 重置数据     reset() {       this.$refs.form.clearValidate();       this.form = {         // parentId: null,         file: [],       };     },   }, }; </script>

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!