最近项目新增一个需求:导出部分列表数据(较少)以及生成的echart图放到一个excel文件中,全部需要在前端完成
exceljs 文档地址
1、安装
//安装
npm install file-saver --save //保存文件使用
npm install exceljs --save
2、引入
//组件中引入
import ExcelJS from 'exceljs'
import fileSave from 'file-saver'
import * as echarts from 'echarts' // 导入图片使用
import $ from 'jquery'
3、导出后端返回数据(需处理)
let data = res.data //接口返回数据
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('Sheet1')
//根据数据自己调整
worksheet.columns = [
{ header: '名称', key: 'name', width: 24 },
{ header: '在线', key: 'countOnline', width: 24 },
{ header: '离线', key: 'countOffline', width: 24 },
{ header: '百分比', key: 'onlineRate', width: 24 }
]
worksheet.getRow(1).font = {
size: 12,
bold: true
}
worksheet.addRows(data)
workbook.xlsx.writeBuffer().then(buffer => {
//这里为type
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' })
fileSave(blob, `设备状况表.xlsx`)
})
如果只是简单导出一些数据 上面即可实现,但是由于还需要将这些数据展示为echart柱状图,并生成图片插入到excel的sheet2中,简单看下 exceljs中有个addImage方法,参数为:base64/filename 与extension
后端可以在Node中使用 node-echarts-canvas 插件直接实现渲染 将图片从插入到excel表中,但是前端无法使用,于是想了个折中的方式,先在页面渲染出一个 echart图标,再使用canvas画出并获取到生成图片的base64字符串,后袖写入到excel中
4、渲染echart 画canvas
//Echarts设置为绝对定位 并设置z-index:-1;
JS部分
//根据后端返回数据做一下echart的配置文件渲染echarts
const source = []
for (const res of res.data) {
const obj = {
在线: res.countOnline,
离线: res.countOffline,
在线率: (res.countOnline / res.countAll).toFixed(2)
}
obj.countType = res.deviceTypeName
source.push(obj)
}
const dataset = {
dimensions: ['countType', '在线', '离线', '在线率'],
source
}
const option = {
legend: {
top: '20%',
right: '30%'
},
grid: {
show: false,
top: '15%',
right: '5%',
bottom: '10%',
left: '10%'
},
tooltip: {},
animation: false,
dataset,
xAxis: {
type: 'category',
textStyle: {
color: 'red',
fontSize: '80',
itemSize: ''
}
},
yAxis: {
textStyle: {
color: 'red',
fontSize: '80',
itemSize: ''
}
},
series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
}
//渲染图表
var myChart = echarts.init(document.getElementById('main'))
myChart.setOption(option)
好了 此时渲染成功,后面就是将图表使用canvas画出来得到base64
//这里部分·可以放在上面workbook.xlsx.writeBuffer()。。。之前 自己封装吧
var baseCanvas = $('.canvas').first()[0]
if (!baseCanvas) {
return false
}
var width = baseCanvas.width
var height = baseCanvas.height
var ctx = baseCanvas.getContext('2d')
ctx.drawImage(baseCanvas, 0, 0, width, height)
let base64 = baseCanvas.toDataURL()
// 此时获取到了渲染的echart图片的base64,后续报表添加sheet2
const picsheet = workbook.addWorksheet('Sheet2')
const imageId2 = workbook.addImage({
base64: base64,
extension: 'png'
})
picsheet.addImage(imageId2, {
tl: { col: 3, row: 4 },
ext: { width: 1600, height: 800 }
})
//生成excel文件
workbook.xlsx.writeBuffer().then(buffer => {
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' })
saveAs(blob, `设备报表.xlsx`)
})
效果如下
sheet2里面如下
后续细节自行调整