列表导出
后台管理系统通常是由各种各样的列表和表单组成。而列表的导出功能也是十分常见,下面是前端处理列表导出的几种方式。
一、接口返回长链接:window.open
如果导出后端可以直接返回文件链接,那么直接打开即可下载。
此方式也最为常见。
二、接口返回二进制流:
在接口请求时增加一个选项:responseType: 'blob'
对于接口返回的文件流数据,有两种处理方式。
一是使用原生 a 标签的下载功能:
/**
* @description 导出并下载文件流
* @method saveFileStream
* @param {String} url
* @returns {Promise}
*/
// filename,摘取了常用的部分,其实还有其他一些 mimetypes
const mimetypesDict = {
'doc': 'application/msword',
'bin': 'application/octet-stream',
'exe': 'application/octet-stream',
'so': 'application/octet-stream',
'dll': 'application/octet-stream',
'pdf': 'application/pdf',
'ai': 'application/postscript',
'ppt': 'application/vnd.ms-powerpoint',
'dir': 'application/x-director',
'js': 'application/x-javascript',
'swf': 'application/x-shockwave-flash',
'xhtml': 'application/xhtml+xml',
'xht': 'application/xhtml+xml',
'zip': 'application/zip',
'mid': 'audio/midi',
'midi': 'audio/midi',
'mp3': 'audio/mpeg',
'rm': 'audio/x-pn-realaudio',
'rpm': 'audio/x-pn-realaudio-plugin',
'wav': 'audio/x-wav',
'bmp': 'image/bmp',
'gif': 'image/gif',
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'png': 'image/png',
'css': 'text/css',
'html': 'text/html',
'htm': 'text/html',
'txt': 'text/plain',
'xsl': 'text/xml',
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml': 'text/xml',
'mpeg': 'video/mpeg',
'mpg': 'video/mpeg',
'avi': 'video/x-msvideo',
'movie': 'video/x-sgi-movie'
}
export function saveFileStream({
fileStream,
fileType,
fileName = `filename-${Date.now()}`
}) {
// 文件下载
let mimetype = mimetypesDict[fileType]
if (!mimetype) {
return new Error('请输入正确的文件格式后缀!')
}
let blob = new Blob([fileStream], { type: `${mimetype};charset=UTF-8` })
// let blob = new Blob([fileStream])
// fullFileName = 'filename' + path.substring(path.lastIndexOf("."), path.length);
let fullFileName = `${fileName}.${fileType}`
downFile(blob, fullFileName)
}
// js下载文件流
function downFile(blob, fileName) {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName)
} else {
var link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = fileName
link.click()
window.URL.revokeObjectURL(link.href)
}
}
saveFileStream({
fileStream: res,
fileType: 'xls', // xsl xls xlsx
fileName: fileName
})
二是使用插件 file-saver
import FileSaver from 'file-saver';
FileSaver.saveAs(
new Blob([fileStream], { type: 'application/octet-stream' }),
'文件名' + parseTime(new Date()) + '.xlsx'
)
三、前端直接导出:利用插件 export-from-json
此插件可将json数据导出为 csv 文件,一般用于直接导出前端列表所展示的数据(适用于不分页的情况)。
import ExportFromJson from 'export-from-json'
// 将json 数组导出到表格 这里 withBOM 是为了防止导出的csv文件使用 Excel 打开出现中文乱码的情况!
export const exportFromJson = (data = [], fileName, exportType = 'csv', withBOM = true) => {
return ExportFromJson({ data, fileName, exportType, withBOM })
}
导出数据需要处理成 key value 的json数据,其中key须是中文。
所以一般情况下都需要将后端返回的列表数据处理之后才能导出。
const tableLabelMap = this.$refs.tableRef.$children.reduce((acc, curr) => {
if (curr.label !== void (0) && curr.prop !== void (0)) {
acc[curr.prop] = curr.label
return acc
}
}, {});
const exportData = this.tableData.map((item) => {
const obj = {}
for (const key in tableLabelMap) {
obj[tableLabelMap[key]] = item[key]
}
return obj
})
console.log(exportData);
exportFromJson(exportData, '文件名字')