导入excel表:
导入excel导入功能vue-element-admin已经提供了,只要基于源码改造即可。
(1):excel导入功能需要使用npm包xlsx,所以需要安装xlsx插件, 使用 npm i xlsx
下载组件。
(2):将vue-element-admin提供的导入功能,新建成一个组件,组件源码地址(cv过去就好了):
https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/UploadExcel/index.vue
得到类似于这样的页面(多少会有点差异,我修改了一下样式):

(3):使用Vue全局注册的方式注册并导入 excel 组件
import UploadExcel from './UploadExcel'
export default {
install(Vue) {
Vue.component('UploadExcel', UploadExcel)
}
}
(4):使用一个中间组件导入,注册在全局的excel组件(为什么要使用一个中间模块呢?因为在excel组件源码中需要传递两个props且为函数,需要使用一个中间组件传参,这是最方便以及简单的办法了)
props: {
beforeUpload: Function,
onSuccess: Function
},
(5):从源码中我们可以看到打开文件按钮其实打开的其实是隐藏域input type 为 file
类型的文件域,其中 @change="handleClick
是用来判断文件域中有无数据,从而决定是否调用upload
函数, upload
函数中判断使用props传过来的参数 beforeUpload
函数是否有值,有值就直接执行并拿到返回值 before
,如果传递了函数 beforeUpload
,并且没有 return
则结束导入,导入失败,如果函数 beforeUpload
有返回值,或者没有传 beforeUpload
则调用函数 readerData
并且把 excel 文件作为形参传递过去,在函数 readerData
中我们可以看到 读取文件是基于原生 FileReader
构造函数,并且返回值是一个Promise对象,在 reader.onload
事件中我们可以看到,header 和 results
这两个返回值被传入到 generateData
函数中,generateData
函数拿到结果后,判断我们是否传递参数 onSuccess
,如果传递,则调用函数传递结果 header 和 results
。
以上我们可以看到使用该组件非常的简单,只需要传递 onSuccess
函数, 如果在 readerData
读取excel表之前还需要做什么操作时就要传递 beforeUpload
函数(一定要有返回值, 否则上传文件失败)。
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
<div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
<el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">打开文件</el-button>
handleUpload() {
this.$refs['excel-upload-input'].click();
},
handleClick(e) {
const files = e.target.files;
const rawFile = files[0];
if (!rawFile) return;
this.upload(rawFile);
},
upload(rawFile) {
this.$refs['excel-upload-input'].value = null;
if (!this.beforeUpload) {
this.readerData(rawFile);
return;
}
const before = this.beforeUpload(rawFile);
if (before) {
this.readerData(rawFile);
}
},
readerData(rawFile) {
this.loading = true;
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: 'array' });
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
const header = this.getHeaderRow(worksheet);
const results = XLSX.utils.sheet_to_json(worksheet);
this.generateData({ header, results });
this.loading = false;
resolve();
};
reader.readAsArrayBuffer(rawFile);
});
},
generateData({ header, results }) {
this.excelData.header = header;
this.excelData.results = results;
this.onSuccess && this.onSuccess(this.excelData);
},
(6):拿到 header
和 results
结果后结果类似于下图:

根据自己的需要的格式进行格式转换,然后调用后台接口就基本完成了,但是excel表中有一个时间问题需要自己转换一下时间格式,该函数我已经写出来并贴在代码区了(这里就不细说了):
formatDate(numb, format) {
const time = new Date((numb - 1) * 24 * 3600000 + 1)
time.setYear(time.getFullYear() - 70)
const year = time.getFullYear() + ''
const month = time.getMonth() + 1 + ''
const date = time.getDate() - 1 + ''
if (format && format.length === 1) {
return year + format + month + format + date
}
return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
}
导出excel表:
1、Excel 的导入导出都是依赖于js-xlsx来实现的, 在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据。
2、由于 Export2Excel不仅依赖js-xlsx还依赖file-saver和script-loader,所以开始前需要下载xlsx file-saver
和 script-loader
两个包:
npm install xlsx file-saver -S
npm install script-loader -S -D
(1):由于js-xlsx体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议使用懒加载。使用方法如下:
import('@/vendor/Export2Excel').then(excel => {
excel.export_json_to_excel({
header: tHeader,
data,
filename: 'excel-list',
autoWidth: true,
bookType: 'xlsx'
})
})
(2):excel导出参数的介绍:
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
header | 导出数据的表头 | Array | / | [] |
data | 导出的具体数据 | Array | / | [[]] |
filename | 导出文件名 | String | / | excel-list |
autoWidth | 单元格是否要自适应宽度 | Boolean | true / false | true |
bookType | 导出文件类型 | String | xlsx, csv, txt, more | xlsx |
(3):我们最重要的一件事,就是把表头和数据进行相应的对应填上 header
和 data
,一个生成表头,一个生成表体,将数据转换好数据结构之后直接传入即可。
(4):我们从上文中说道excel表有时间问题,其excel时间与js时间对应不上,我们存入的时候做了时间转换,所以现在拿出也要做时间转换,代码如下:
function formatDate(date, fmt = 'yyyy-MM-dd') {
if (!(date instanceof Array)) {
date = new Date(date);
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
const str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
}
复杂表头的导出:
excel中复杂表头的导出方法 主要是 multiHeader
和 merges
两个参数
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
multiHeader | 复杂表头的部分 | Array | / | [[]] |
merges | 需要合并的部分 | Array | / | []] |
multiHeader里面是一个二维数组,里面的一个元素是一行表头,假设你想得到一个如图的结构mutiHeader应该这样定义:
const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
multiHeader中的一行表头中的字段的个数需要和真正的列数相等,假设想要跨列,多余的空间需要定义成空串它主要对应的是标准的表头
const header = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
如果,我们要实现其合并的效果, 需要设定merges选项
const merges = ['A1:A2', 'B1:F1', 'G1:G2']
merges的顺序是没关系的,只要配置这两个属性,就可以导出复杂表头的excel了
最后配置项:
excel.export_json_to_excel({
header: Object.keys(headers),
data,
filename: '员工资料表',
multiHeader,
merges
})