vue基于exceljs导出excel实战⽰例
背景
在做⼀个⼩东西,需要导出excel,之前导出excel 的⽅式都是在服务器端,⽣成excel然后在浏览器端进⾏下载,这次想进⾏在前端进⾏导出,基于这个需求在⽹上了⼀些⼯具,这⾥会做⼀些对⽐
⼯具对⽐
名
称
优点缺点活跃度⽀持nodejs服务端和兼容⼤多数浏览器导出,读写⽀持完美社区版本不⽀持样式定制15867
⽀持nodejs服务端和兼容⼤多数浏览器导出,读写⽀持完美,活跃度很
⾼,使⽤简单
国内使⽤的⼈很少,并且相关⽰例很少3794
基于xlsx的做的,⽀持xlsx原来所有的api也⽀持样式定制⽆法直接使⽤有很多pr并没有任何并,活跃度很低,最近⼀次更
新是2017年
334
轻量级,可以定制样式导⼊⽀持的并不是很好,活跃度并不是很好,最近⼀次更新2017
年
18
经过多⽅对⽐,最终选择⽤exceljs来做导出excel的⼯具库,因为开发着⾮常活跃,截⾄现在,⼏个⼩时之前还有更新,并且全⾯⽀持excel的读和写。下⾯来点⼲活,直接上代码
使⽤⽰例
1. 导⼊包
npm install exceljs
2. 封装的导出⼯具类,该⼯具类⽀持多sheet导出,⽀持多表头处理,默认会给表格加上边框的样式
require('script-loader!file-saver')
import*as ExcelJs from'exceljs/dist/exceljs'
/**
* ⽀持多sheet 导出excel
* @param multiHeader 多⾏表头
* @param headers 多sheet对应的表头
* @param datas 数据,⼀个数组表⽰⼀个sheet中的数据
* @param filename ⽂件名称
* @param sheetnames sheet名称,数组格式的,数组中按次获取sheet名称
* @param merges 合并单元格未实现
* @param autoWidth ⾃动列宽
* @param bookType ⽂档类型
*/
export function export_json_to_excel_sheet({
multiHeader =[],
headers =[],
datas =[],
filename,
js合并两个数组sheetnames =[],
merges =[],
autoWidth =true,
bookType ='xlsx'
}={}){
// 创建⼀个⼯作簿
const workbook =new ExcelJs.Workbook()
// 遍历数据
for(let tmp =0; tmp <= datas.length -1; tmp++){
// 获取数据
const data = datas[tmp]
// 添加表头, 合并表头的数据
// 添加表头, 合并表头的数据
const header = headers[tmp]
data.unshift(header)
// 多⾏标头
for(let i = multiHeader.length -1; i >-1; i--){
data.unshift(multiHeader[i])
}
// 获取sheetname
var ws_name = sheetnames[tmp]
// add header
const ws1 = workbook.addWorksheet(ws_name)
ws1.addRows(data)
// ⾏居中
rowCenter(ws1,1+ multiHeader.length, data.length)
// ⾃动处理列宽
if(autoWidth){
/* 设置worksheet每列的最⼤宽度*/
const columnWidth = data.map(row => row.map(val =>{
/* 先判断是否为null/undefined*/
if(val ==null){
return{
'width':10
}
// eslint-disable-next-line brace-style
}
/* 再判断是否为中⽂*/
else String().charCodeAt(0)>255){
return{
'width': String().length *2
}
}else{
return{
'width': String().length
}
}
}))
/* 以第⼀⾏为初始值*/
const result = columnWidth[0]
for(let i =1; i < columnWidth.length; i++){
for(let j =0; j < columnWidth[i].length; j++){
if(result[j]['width']< columnWidth[i][j]['width']){
result[j]['width']= columnWidth[i][j]['width']
}
}
}
// 设置列宽
colWidth(ws1, result)
}
}
/**
* 设置start-end⾏单元格⽔平垂直居中/添加边框
* @param arg_ws workSheet 参数
* @param arg_start 开始⾏
* @param arg_end 结束结束⾏
*/
function rowCenter(arg_ws, arg_start, arg_end){
// eslint-disable-next-line no-undef,no-unmodified-loop-condition
let i = arg_start
for(; i <= arg_end; i++){
arg_ws.findRow(i).alignment ={ vertical:'middle', horizontal:'center'} // eslint-disable-next-line no-irregular-whitespace
// 循环 row 中的 cell,给每个 cell添加边框
arg_ws.findRow(i).eachCell(function(cell, index){
cell.border ={
top:{ style:'thin'},
left:{ style:'thin'},
bottom:{ style:'thin'},
right:{ style:'thin'}
}
})
}
}
// eslint-disable-next-line no-irregular-whitespace
// 设置 start-end 列的宽度
/**
* 设置⾏宽
* @param arg_ws workSheet
* @param arg_cols 列数组
*/
function colWidth(arg_ws, arg_cols){
for(const i in arg_cols){
Column(parseInt(i)+1).width = arg_cols[i].width
}
}
// 保存设置
workbook.xlsx.writeBuffer().then(buffer =>{
// eslint-disable-next-line no-undef
saveAs(new Blob([buffer],{
type:'application/octet-stream'
}),`${filename}.${bookType}`)
})
}
3. 然后再vue中就可以使⽤该⼯具类,⽤法如下
import('@/vendor/Export2ExcelJs').then(excel =>{
const tHeader =['测试1','测试2','测试3','测试4','测试5']
const filterVal =['test','test2','test3','test4','test5']
const list =portlist
let text ='测试'
const s =parseTime(this.begin,'{y}-{m}-{d}')+'⾄'+d,'{y}-{m}-{d}')
this.filename = s + text +'测试汇总表'
const data =this.formatJson(filterVal, list)
const multiHeader =[['','','xxx系统','',''],['','','xxx汇总表','',''],['查询⽇期:'+ s,'','','','查询范围:'+ text]] console.log(data)
headers:[tHeader],
datas:[data],
multiHeader: multiHeader,
sheetnames:['xxx汇总表'],
filename:this.filename,
autoWidth:this.autoWidth,
bookType:this.bookType
})
this.downloadLoading =false
})
this.listLoading =false
})
格式化代码如下
formatJson(filterVal, jsonData){
return jsonData.map(v => filterVal.map(j =>{
if(j ==='createdDate'){
return parseTime(v[j],'{y}-{m}-{d}')
}else{
if(j.indexOf('.')>0){
const t = j.split('.')
return v[t[0]][t[1]]
}
return v[j]
}
}))
}
到这⾥本次⽂章到此结束
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论