Vue+Element 实现前端导出Excel

2,262 阅读3分钟
打劫小赞赞 !!!!!

关注个人微信订阅号: 前端技术与生活

1、开始准备

1.1 业务场景

由前端导出Excel表格,根据后台获取到的数据

2、实现原理的两种方法

2.1 第一种方法

引入工具库 xlsx、script-loader、file-saver

此时还需要引入两个JS文件

require('script-loader!file-saver')
require('script-loader!./Blob')
import XLSX from 'xlsx'

参考下载地址:

    https://github.com/Yujian0107/Excel-

2.2修改JS中的文件地址

打开Export2Excel.js,会出现下图所示,本人是将Blob.js和Export2Excel.js放到了同一级,所以引入是这样的。

//目录结构
    |Blob.js
    |Export2Excel.js
    |index.js

注:除了xlsx 可以使用 import 引入,其他需要 script-loader 来将他们挂载到全局环境下

2.3 导出函数

import { export_json_to_excel } from './Export2Excel'

// 导出的函数
export const exportExcel = (title, multiHeader, merges, excelData, tHeader, filterVal, excelName) => {
  export_json_to_excel({
    title,
    multiHeader,
    merges,
    header: tHeader,
    data: excelData,
    filename: excelName
  });
};

页面引入 improt { exportExcel formatJson } form '放置函数的文件路径'

title: 表头

multiHeader 为2级表头(根据业务场景是否有层级表头)

merges 一个合并列宽的数组 格式:["A1":"H1"] 表示表格第一行从A1开始合并到H1 (不清楚可以去看一下Excel表格)

THeader 为导出Execl表头名称,也就是表格的label名

data 为传入的数组(如[{name:'小白'}]),传入之前需要把数组转化成Json格式

//数据格式转化函数
export function formatJson(filterVal, jsonData) {
  return jsonData.map(v => filterVal.map(j => v[j]))
}

fillterVal 是一个数组这个这个数组是对应显示页面的表头字段(参数)如:['name'],转化JSON格式的时候需要把这个数组和data输入一并传入formatJson函数里

filename 也就是文件名了

到这里第一种方法以及完毕 !!!第二种方法更为强大比第一张更加全面

3、第二种方法 工具名 xlsx-populate

3.1 安装还是一如既往

npm install xlsx-populate

3.2 引入工具

import XlsxPopulate from 'xlsx-populate'

然后爆出一个全局函数

//导出函数
export const handleExport = (excelName, callBack, execlData, param = '') => {
    XlsxPopulate.fromBlankAsync()
        .then(workbook => {
          let sheet = workbook.sheet("Sheet1");
          callBack(sheet, excelName, execlData, param);
          workbook.outputAsync().then(function (blob) {
            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
              // If IE, you must uses a different method.
              window.navigator.msSaveOrOpenBlob(blob, `${excelName}.xlsx`);
            } else {
              let url = window.URL.createObjectURL(blob);
              let a = document.createElement('a');
              document.body.appendChild(a);
              a.href = url;
              a.download = `${excelName}.xlsx`;
              a.click();
              window.URL.revokeObjectURL(url);
              document.body.removeChild(a);
            }
        });
    });
};

sheet 是工作表

excelName 文件名

execlData 也就是导出数据了

callBack 也就是你要开始绘画的一个函数

callBack 函数

//绘画Excel表格以及样式
export const handleExportTable = (sheet, execlName, execlData) => {
  console.log(execlData,'数据')
  sheet.range(`A1:H1`).merged(true).value(execlName).style({
    fontSize: 18,
    fontFamily: 'FZXBSJW',
    horizontalAlignment: 'center',
    verticalAlignment: 'center',
  });
  sheet.range(`A2:A3`).merged(true).value("时间").style(rangeStyle);
  sheet.range(`B2:B3`).merged(true).value("").style(rangeStyle);
  sheet.column('B').width(25);
  sheet.range(`C2:C3`).merged(true).value("").style(rangeStyle);
  sheet.range(`D2:D3`).merged(true).value("").style(rangeStyle);
  sheet.range(`E2:G2`).merged(true).value("").style(rangeStyle);
  sheet.range(`E3:E3`).merged(true).value("").style(rangeStyle);
  sheet.column('E').width(15);
  sheet.range(`F3:F3`).merged(true).value("").style(rangeStyle);
  sheet.column('F').width(20)
  sheet.range(`G3:G3`).merged(true).value("").style(rangeStyle);
  sheet.column('G').width(20);
  sheet.range(`H2:H3`).merged(true).value("").style(rangeStyle);
  execlData.map((item, index) => {
    sheet.cell(`A${index+4}`).value(cxDateFilter(item.time)).style({
      fontSize: 10,
      fontFamily: '黑体',
      horizontalAlignment: 'center',
      verticalAlignment: 'center',
      wrapText: true
    });
    sheet.cell(`B${index+4}`).value((item && item.target).display_name + item.target_note).style(rangeStyle);
    sheet.cell(`C${index+4}`).value(item.location).style(rangeStyleText);
    sheet.cell(`D${index+4}`).value(item.method).style(rangeStyleText);
    sheet.cell(`E${index+4}`).value(dataFilter(item.cost_time)).style(rangeStyle);
    sheet.cell(`F${index+4}`).value(item.device_case).style(rangeStyleText);
    sheet.cell(`G${index+4}`).value(item.result).style(rangeStyleText);
    sheet.cell(`H${index+4}`).value(item.checker).style(rangeStyle);
  })
}

这只是其中一个表格的绘画如果你表格都是一样的你可以封装成通用的

range 表格的范围

merged 是否合并

value 当前范围的文字

style 当前范围的样式

column 单元格所在的宽度

row 设置列的高度

sheet("Sheet1").column('A').width(100)
sheet("Sheet1").row(1).height(100)

cell 设置单元格的内容 为什么我这里是index+4 因为我的表头个层级表头占了3层 至于为什么占了3层 要加4 体会一下

接下来还是一样的链式操作内容和样式

具体在页面使用如下图:

引入callBack函数和全局函数

import { handleExport } from '@/vendor/index'
import { handleExportTable } from '@/excelExport/index'

导出使用

exportTable(excelData,excelName){
    if(_.isEmpty(excelData))return this.$message.error('无数据不可导出');
    handleExport(execlName,handleExportTable,execlData);
    this.$message.success('导出成功');
}

有更好的方式交流一下 !!!!

公众号搜索

前端技术与生活