// 题目导入模板下载接口 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 }) } import { exportTemplate, importTemplate, } from "@/api/edu/question"; //引用下载文件的方法 import { download } from "@/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:
下载 选取文件 确 定 取 消 VUEJS:
下一篇:泛型如何定义和使用?