Vue结合js-xlsx实现Excel的导入导出

之前有做过Excel导出的需求,但是有点云里雾里,最近有空就想再去研究研究其中的精彩。于是,就有了这篇博客。

首先介绍一下js-xlsx。

SheetJS是前端操作Excel以及类似的二维表的最佳选择之一,而js-xlsx是它的社区版本.

js-xlsx将注意力集中到了数据转换和导出上,所以它支持相当多种类的数据解析和导出.不仅仅局限于支持xlsx格式。

GitHub地址为https://github.com/SheetJS/js-xlsx。

要使用js-xlsx需要先引入,

import XLSX, { utils } from 'xlsx'

我们主要用到了XLSX的writeFile()方法和read()方法,untils是XLSX封装的工具类,里面提供了很多工作表对象转换为其他类型或者其他类型转换为工作表对象的方法。这里我们主要用到了sheet_to_json和aoa_to_sheet,table_to_sheet等方法。

废话不多说,先看代码。

/**
     * @description                  依据数据导出表格,一般是根据查询出的数据导出表格
     * @param {Object} option        Object--配置对象
     * @param option.title      Array--表头,即表格首行展示的内容,如:['姓名','年龄','性别','地址']
     * @param option.body       Array--表格内容,二维数组,每一行的内容为一个数组,与表头对应,如:[['王小虎',28,'男','aa'],['王大虎',29,'男','aa']]
     * @param option.name       String--文件名,如:'demo'
     * @param option.suffix     String--文件后缀名,如'csv'
     * @param option.merges     Array--表格的单元格合并信息,如[
          { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } },-----表示A1和A2单元格合并
          { s: { r: 0, c: 1 }, e: { r: 0, c: 2 } },-----表示B1和C1单元格合并
          { s: { r: 0, c: 3 }, e: { r: 0, c: 4 } },-----表示D1和E1单元格合并
          { s: { r: 0, c: 5 }, e: { r: 1, c: 5 } }-----表示F1和F2单元格合并
        ]------s:start,e:end,r:row,c:cell;
     */
    exportFromArray(option) {
        const config = Object.assign({}, { name: 'demo', suffix: 'csv' }, option)
        const { title, body, name, suffix, merges } = config;
        const array = [...title, ...body];
        const workBook = utils.book_new();//创建workBook
        const workSheet = utils.aoa_to_sheet(array);//将数组转换成workSheet
        const fileName = name + '.' + suffix;
        workSheet['!merges'] = merges;
        utils.book_append_sheet(workBook, workSheet, name);
        XLSX.writeFile(workBook, fileName, { bookType: suffix, type: 'buffer' })
    }

这是查询出的数据导出Excel的方法

/**
     * @description                      依据网页中的表格导出文件,只导出网页中的表格数据
     * @param {Object} option            配置对象
     * @param {string} option.id         表格在dom中的id,必传
     * @param {string} option.name       String--文件名,如:'demo'
     * @param {string} option.suffix     String--文件后缀名,如'csv'
     */
    exportFromTable(option) {
        const config = Object.assign({}, { name: 'demo', suffix: 'csv',sheetName:'信息表' }, option),
            { id, name, suffix, merges,sheetName } = config,
            workBook = utils.book_new(),
            workSheet = utils.table_to_sheet(document.getElementById(id)),
            fileName = name + '.' + suffix;
        workSheet['!merges'] = merges;
        utils.book_append_sheet(workBook, workSheet, sheetName);
        XLSX.writeFile(workBook, fileName, { bookType: suffix, type: 'buffer' })
    }

这是表格导出Excel的方法。

/**
     * @description  解析表格文件数据,返回表格中内容,目前暂不支持导入有单元格合并的表格
     * @param    {Object} file    导入的文件,二进制数据流
     * @returns  {Object} data    返回的表格数据
     * @returns  {Array}  data.title   表头
     * @returns  {Array}  data.body    表格数据
     */
    async importFromLocal(file) {
        const workBook = await this.readerWorkBookFromLocal(file),
            workSheet = workBook.Sheets[workBook.SheetNames[0]],
            content = utils.sheet_to_json(workSheet),
            data = {};
        data.title = Object.keys(content[0]);
        data.body = content;
        return data;
    },
    /**
     * @description              本地读取文件的方法
     * @param {Object} file      文件流
     */
    readerWorkBookFromLocal(file) {
        const reader = new FileReader();
        reader.readAsBinaryString(file);
        return new Promise(function (resolve, reject) {
            reader.onload = function (e) {
                const fileData = e.target.result;
                if (reader.readyState === 2) {
                    const workBook = XLSX.read(fileData, { type: 'binary' });
                    resolve(workBook);
                } else {
                    reject('读取文件失败');
                }
            }
        })
    }

这两个方法是导入Excel的方法。

导出效果如下:

Vue结合js-xlsx实现Excel的导入导出_第1张图片

导入效果如下:

Vue结合js-xlsx实现Excel的导入导出_第2张图片

 

项目地址:https://github.com/wangchaochuan/excel-demo

有兴趣的可以到我的GitHub上下载这个项目瞅一瞅。好久没写博客了,感觉都不回写了

你可能感兴趣的:(vue)