likes
comments
collection
share

基于 Vue 的 Web 端和 Electron 桌面端导出 Excel 表格

作者站长头像
站长
· 阅读数 14

前言

基于Vue导出Excel表格的总结。项目使用的vue版本为 2.6.10,vue-cli版本为 3.12.1,node版本为 v14.17.5,electron版本为 12.0.0

※注:本文代码区域每行开头的“+”表示新增,“-”表示删除,“M”表示修改;代码中的“...”表示省略。

excel中的名词解释

workbook 等同于excel文件,worksheet等同于文件中的一个个工作簿Sheet1,Sheet2,Sheet3。一开始看文档时关于workbook 和 worksheet 也是一头雾水,后查阅资料后在此记载。

1 安装项目依赖

本方法依赖插件 xlsx,文档地址:github.com/SheetJS/she…

安装依赖,下载指定版本的 xlsx,防止版本升级后的兼容性问题

npm install xlsx@0.16.9

在需要用到的文件中引入

import XLSX from 'xlsx'

2 Web 端导出 Excel

2.1 数据方式导出

此方法适用于 element-ui 中的表格,或其他不是由一个 table 标签组成的形如表格的数据。总之给出数据,就可以输出excel.

	import XLSX from 'xlsx'   
	...
	/**
     * 导出电子表格
     * @param {Array<array>} header 头部数据, 为二维数组,按顺序输出
     * @param {Array<object>} body 表格body数据,按Object.keys() 顺序输出
     * @param {String} format 输出表格格式,默认 'xlsx'
     */
    exportSpreadsheet({ header, body, format = 'xlsx' }) {
        // 表头数据:官方文档中的描述:converts an array of arrays of JS data to a worksheet.
        const headerWs = XLSX.utils.aoa_to_sheet(header)
        // console.log(JSON.stringify(body) );

        // 定义 worksheet 的格式
        const ws = XLSX.utils.sheet_add_json(headerWs, body, {
            skipHeader: true,
            origin: 'A2',
        })

        /* 新建空workbook,然后加入worksheet */
        const wb = XLSX.utils.book_new()

        // 往 workbook 中加入worksheet,可以自定义下载之后的sheetname
        XLSX.utils.book_append_sheet(wb, ws, 'sheetName')

        /* 生成xlsx文件,attempts to write wb to filename. In browser-based environments, it will attempt to force a client-side download */
        XLSX.writeFile(
            wb,
            `${this.formatDate(new Date(), 'current')}.${format}`,
            {
                bookType: format, // Type of Workbook, default "xlsx"
                bookSST: true, // Generate Shared String Table **, default false
            }
        )
    }
	...
export { exportSpreadsheet }

示例:

import {exportSpreadsheet} from '@/xxx' 

header:[["用户ID","用户姓名","用户账号","事件状态","事件状态描述","事件ID","事件类型","事件时间","客户端类型","记录创建时间","客户端类型名称","客户端信息"]]

body:[{clientInfo: "Chrome",clientTypeName: "Windows",createDetetime: "2022-02-15 15:15:47",eventDatetime: "2022-02-15 15:15:48",eventType: "登录",logonEventId: 402,message: "登录成功",status: "成功",userAccount: "admin",userId: 1001,userLastname: "管理员",}]

exportSpreadsheet(header,body)

输出结果:

基于 Vue 的 Web 端和 Electron 桌面端导出 Excel 表格

注意:formatDate 为时间格式化方法 ,输出文件名为当前日期+时分秒

2.2 DOM方式导出

此方法适用于原生 html 的 table 标签导出 excel 表格

    import XLSX from 'xlsx'   
	...
	/**
     * 导出 excel 表格
     * @param {DOMObject} table 获取的 table DOM 元素
     */
    exportExcelByDOM(table) {
        if (table) {
            // wb(workbook):  XLSX.writeFile 写文件时传入的第一个参数
            // raw: 保持 原始的 string 格式输出, 这样时间格式不会错乱
            let wb = XLSX.utils.table_to_book(table, {
                raw: true,
            })
            let format = 'xlsx'

            XLSX.writeFile(wb, res.filePath, {
                 bookType: format, // Type of Workbook, default "xlsx"
                 bookSST: true, // Generate Shared String Table **, default false
            })
    },
    ...
    export { exportExcelByDOM }

示例:

import {exportExcelByDOM} from '@/xxx' 
let table = document.querySelector('.table')
exportExcelByDOM(table)

输出结果:和网页中 table 元素一致

3 Electron 桌面端导出 Excel

3.1 数据方式导出

	import XLSX from 'xlsx' 
	const { dialog } = require('electron').remote
	...
	/**
     * 导出电子表格
     * @param {Array<array>} header 头部数据, 为二维数组,按顺序输出
     * @param {Array<object>} body 表格body数据,按Object.keys() 顺序输出
     * @param {String} format 输出表格格式,默认 'xlsx'
     */
    exportSpreadsheet({ header, body, format = 'xlsx' }) {
        // 表头数据:官方文档中的描述:converts an array of arrays of JS data to a worksheet.
        const headerWs = XLSX.utils.aoa_to_sheet(header)
        // console.log(JSON.stringify(body) );

        // 定义 worksheet 的格式
        const ws = XLSX.utils.sheet_add_json(headerWs, body, {
            skipHeader: true,
            origin: 'A2',
        })

        /* 新建空workbook,然后加入worksheet */
        const wb = XLSX.utils.book_new()

        // 往 workbook 中加入worksheet,可以自定义下载之后的sheetname
        XLSX.utils.book_append_sheet(wb, ws, 'sheetName')

       dialog.showSaveDialog({
            title: '保存文件',
            defaultPath: `${formatDate(new Date(), 'current')}.${format}`,
            filters: [{ name: 'All Files', extensions: [format] }],
        })
        .then((res) => {
            // console.log(res, screenShootBlob)
            if (res.filePath) {
                // console.log(res.filePath)

                XLSX.writeFile(wb, res.filePath, {
                    bookType: format, // Type of Workbook, default "xlsx"
                    bookSST: true, // Generate Shared String Table **, default false
                })
            }
        })
    }
	...
export { exportSpreadsheet }

示例:

import {exportSpreadsheet} from '@/xxx' 

header:[["用户ID","用户姓名","用户账号","事件状态","事件状态描述","事件ID","事件类型","事件时间","客户端类型","记录创建时间","客户端类型名称","客户端信息"]]

body:[{clientInfo: "Chrome",clientTypeName: "Windows",createDetetime: "2022-02-15 15:15:47",eventDatetime: "2022-02-15 15:15:48",eventType: "登录",logonEventId: 402,message: "登录成功",status: "成功",userAccount: "admin",userId: 1001,userLastname: "管理员",}]

exportSpreadsheet(header,body)

输出结果:

基于 Vue 的 Web 端和 Electron 桌面端导出 Excel 表格

注意:formatDate 为时间格式化方法 ,输出文件名为当前日期+时分秒

3.2 DOM方式导出

此方法适用于原生 html 的 table 标签导出 excel 表格

    import XLSX from 'xlsx'   
	const { dialog } = require('electron').remote
	...
	  /**
     * 导出 excel 表格
     * @param {DOMObject} table 获取的 table DOM 元素
     */
    exportExcelByDOM(table) {
        if (table) {
            // wb(workbook):  XLSX.writeFile 写文件时传入的第一个参数
            // raw: 保持 原始的 string 格式输出, 这样时间格式不会错乱
            let wb = XLSX.utils.table_to_book(table, {
                raw: true,
            })
            let format = 'xlsx'

            dialog
                .showSaveDialog({
                    title: '保存文件',
                    defaultPath: `${formatDate(
                        new Date(),
                        'current'
                    )}.${format}`,
                    filters: [{ name: 'All Files', extensions: [format] }],
                })
                .then((res) => {
                    // console.log(res, screenShootBlob)
                    if (res.filePath) {
                        // console.log(res.filePath)

                        XLSX.writeFile(wb, res.filePath, {
                            bookType: format, // Type of Workbook, default "xlsx"
                            bookSST: true, // Generate Shared String Table **, default false
                        })
                    }
                })
        }
    }
    ...
    export { exportExcelByDOM }

示例:

import {exportExcelByDOM} from '@/xxx' 
let table = document.querySelector('.table')
exportExcelByDOM(table)

输出结果:和网页中 table 元素一致