最近项目新增一个需求:导出部分列表数据(较少)以及生成的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;
 <div class="Echarts">
      <div id="main" style="width: 2000px;height: 2000px;"></div>
      <canvas class="canvas" width="2000" height="1000"></canvas>
 </div>

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里面如下

 

后续细节自行调整

 

 

Logo

前往低代码交流专区

更多推荐