最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue前端导出Excel文件实现方案

    正文概述 掘金(wallee59)   2021-01-24   998

    一、技术选型

    1.使用 vue-json-excel 插件实现(快速上手)

    优点:简单便捷,易上手,开箱即用;

    缺点:不支持 excel 表格样式设置,且支持功能比较单一;

    2.基于 sheetJS-xlsx 解析器的 xlsx-style 实现(推荐)

    优点:支持格式众多,支持 excel 表格样式设置,功能强大,可控性高,可读取和导出excel;

    缺点:使用较为复杂,上手成本较大,且高级功能需要收费,但该功能可以借助 xlsx-style 实现;

    二、技术实现

    使用 vue-json-excel 插件实现

    1.安装 vue-json-excel 依赖

    npm install -S vue-json-excel
    

    2.注册插件到 vue 实例

    import Vue from "vue";
    import JsonExcel from "vue-json-excel";
    
    Vue.component("downloadExcel", JsonExcel);
    

    3.使用方式

    在需要触发导出事件的外出包裹 download-excel 组件

    该组件支持的属性可参考vue-json-excel 的 github 文档

    <download-excel :data="json_data">
      Download Data
      <img src="download_icon.png" />
    </download-excel>
    

    首先需要处理导出到 excel 文件的数据内容,分别是以下数据:

    • 表头名数据 json_fields:可以选择要导出的字段,并为字段分配标签。该数据类型为 Object ,key 对应的是标签,value 对应的是 JSON 字段,将导出与数据列表相同字段的数据。如果需要自定义导出的数据,可以定义回调函数。
    • 表格数据 json_data:该数据类型为 Array,存储了需要导出的数据内容;
    let json_fields = {
      // fieldLabel(表头名),attributeName(对应字段名)
      fieldLabel: attributeName,
      // 使用回调自定义导出数据
      anotherFieldLabel: {
        field: anotherAttributeName,
        callback: (value) => {
          return `formatted value ${value}`;
        },
      },
    };
    
    let json_data = [
        {
            attributeName: value1,
            anotherAttributeName: value2
        },
        {
            attributeName: value3,
            anotherAttributeName: value4
        }
    ];
    

    处理完数据之后则可以将数据传入 download-excel 组件中,该组件没有任何样式,只需要设置内部包裹的元素样式即可;

    <download-excel
      class="btn btn-default"
      :data="json_data"
      :fields="json_fields"
      worksheet="My Worksheet"
      name="filename.xls"
    >
      Download Excel (you can customize this with html code!)
    </download-excel>
    

    然而在实际的业务场景下,导出表格数据通常是导出表格的所有数据,所以在导出的过程中,需要调用请求接口去获取表格中的所有数据,而调用接口获取数据是异步执行的过程,该插件也针对这个场景提供了解决方案。

    相关案例:

    <template>
        <div id="app">
            <downloadexcel
                class            = "btn"
                :fetch           = "fetchData"
                :fields          = "json_fields"
                :before-generate = "startDownload"
                :before-finish   = "finishDownload">
                Download Excel
            </downloadexcel>
        </div>
    </template>
    
    <script>
    import downloadexcel from "vue-json-excel";
    import axios from 'axios';
    
    export default {
        name: "App",
        components: {
            downloadexcel,
        },
        data(){
            return {
                json_fields: {
                    'Complete name': 'name',
                    'Date': 'date',
                },
            }
        }, //data
        methods:{
            async fetchData(){
                const response = await axios.get(URL);
                return response.data.holidays;
            },
            startDownload(){
                alert('show loading');
            },
            finishDownload(){
                alert('hide loading');
            }
        }
    };
    </script>
    

    基于 sheetJS-xlsx 解析器的 xlsx-style 实现(推荐)

    这里只对封装的 export2Excel 使用方法进行说明,暂时不对原理进行讲解。

    该插件不仅支持 excel 文件的导出,也支持文件导入功能,并且导出 excel 文件的不仅支持 json 数据,也支持 table 导出;

    由于 sheetjs-xlsx 提供的工具库其高级功能是付费项目,如修改表格样式等功能,因此选用了基于 sheetjs-xlsx 实现的 xlsx-style 插件。

    兼容性: Vue前端导出Excel文件实现方案

    1.安装依赖

    npm install -S xlsx
    npm install -S style-xlsx
    

    而 xlsx-style 插件在使用的时候会报错,官方也对该问题给出了解决方案,就是在根目录下的vue.config.js配置文件添加如下代码:

    module.exports = {
    	configureWebpack: {
        	externals: {
          		'./cptable': 'var cptable'
        	}
      	}
    }
    

    还有一种方案是改源代码,但不推荐使用,就不做说明了。

    2.使用方法

    这里封装了 json 导出 excel 文件的方法,其中,文件下载的功能有两个方案实现,分别是:

    • 通过 a 标签的文件下载功能,利用 URL.createObjectURL 方法生成下载链接实现;(本文使用的方法)
    • 通过第三方插件 file-saver 插件实现文件下载功能;

    js-xlsx 插件封装了相关的函数去方便实现不同数据格式的转换:

    • aoa_to_sheet converts an array of arrays of JS data to a worksheet.
    • json_to_sheet converts an array of JS objects to a worksheet.
    • table_to_sheet converts a DOM TABLE element to a worksheet.
    • sheet_add_aoa adds an array of arrays of JS data to an existing worksheet.
    • sheet_add_json adds an array of JS objects to an existing worksheet.

    下面是封装的 export2Excel 函数具体代码,只需要将代码复制到创建的 export2Excel.js 文件中即可:

    /**
     * create by lwj
     * @file 导出export插件封装
     */
    
    import * as styleXLSX from 'xlsx-style'
    
    /**
     * 将 String 转换成 ArrayBuffer 
     * @method 类型转换
     * @param {String} [s] wordBook内容
     * @return {Array} 二进制流数组
     */
    function s2ab (s) {
        let buf = null;
    
        if (typeof ArrayBuffer !== 'undefined') {
            buf = new ArrayBuffer(s.length);
            let view = new Uint8Array(buf);
    
            for (let i = 0; i != s.length; ++i) {
                view[i] = s.charCodeAt(i) & 0xFF;
            }
    
            return buf;
        }
    
        buf = new Array(s.length);
    
        for (let i = 0; i != s.length; ++i) {
    
            // 转换成二进制流
            buf[i] = s.charCodeAt(i) & 0xFF;
        }
    
        return buf;
    }
    
    /**
     * 方案一:利用 URL.createObjectURL 下载 (以下选用)
     * 方案二:通过 file-saver 插件实现文件下载
     * @method 文件下载
     * @param {Object} [obj] 导出内容 Blob 对象
     * @param {String} [fileName] 文件名 下载是生成的文件名
     * @return {void}
     */ 
    function saveAs (obj, fileName) {
        let aLink = document.createElement("a");
    
        if (typeof obj == 'object' && obj instanceof Blob) {
            aLink.href = URL.createObjectURL(obj); // 创建blob地址
        }
        
        aLink.download = fileName;
        aLink.click();
        setTimeout(function () {
            URL.revokeObjectURL(obj);
        }, 100);
    }
    
    /**
     * @method 数据导出excel
     * @param {Object} [worksheets] 工作表数据内容
     * @param {String} [fileName='ExcelFile'] 导出excel文件名
     * @param {String} [type='xlsx'] 导出文件类型
     */
    export default function export2Excel ({
        worksheets, 
        fileName = 'ExcelFile',
        type = 'xlsx'
    } = {}) {
    
        let sheetNames = Object.keys(worksheets);
        let workbook = {
            SheetNames: sheetNames, //保存的工作表名
            Sheets: worksheets
        };
    
        // excel的配置项
        let wopts = {  
            bookType: type,  // 生成的文件类型
            bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
            type: 'binary'  
        }
    
        // attempts to write the workbook
        let wbout = styleXLSX.write(workbook, wopts);
        let wbBlob = new Blob([s2ab(wbout)], {
            type: "application/octet-stream"
        });
    
        saveAs(wbBlob, fileName + '.' + type);
    }
    

    需要注意几个问题:

    1. xlsx 和 style-xlsx 的默认导出函数名都是 XLSX ,如果同时导入的话,需要注意设置别名,避免函数覆盖出现问题;
    2. 如果不想使用 xlsx 插件,只使用 style-xlsx 插件同样也是可以的,只是要自己将需要导出的数据转换成 worksheet 格式对象,其原理也就是将导出数据转换成 worksheet 规定的数据格式,具体可以查看 js-xlsx 文档说明;(可以自己尝试实现)

    然后只需要在需要导出 excel 的地方调用即可,如果对导出表格样式有要求的情况下,需要去了解如何配置表格样式,具体配置方法可以去 style-xlsx 文档 中查看。

    如果是 json 数据导出,需要对表头名和字段进行映射;

    相关案例:

    
    import XLSX from 'xlsx';
    import export2Excel from '@/assets/utils/export2Excel';
    
    let jsonTable = [{
        "sheet1id": 1,
        "表头1": "数据11",
        "表头2": "数据12",
        "表头3": "数据13",
        "表头4": "数据14"
    }, {
        "sheet1id": 2, 
        "表头1": "数据21",
        "表头2": "数据22",
        "表头3": "数据23",
        "表头4": "数据24"
    }];
    
    let aoa = [
        ['sheet2id', '表头1', '表头2', '表头3', '表头4'],
        [1, '数据11', '数据12', '数据13', '数据14'],
        [2, '数据21', '数据22', '数据23', '数据24']
    ]
    
    function handleExportExcel () {
        
        // 使用 XLSX 内置的工具库将 json 转换成 sheet
        let worksheet1 = XLSX.utils.json_to_sheet(jsonTable);
    
        // 使用 XLSX 内置的工具库将 aoa 转换成 sheet
        let worksheet2 = XLSX.utils.aoa_to_sheet(aoa);
    
        // 设置 excel 表格样式
        worksheet1["B1"].s = { 
            font: { 
                sz: 14, 
                bold: true, 
                color: { 
                    rgb: "FFFFAA00"
                } 
            }, 
            fill: { 
                bgColor: { 
                    indexed: 64 
                }, 
                fgColor: { 
                    rgb: "FFFF00" 
                } 
            } 
        };
    
        // 单元格合并
        worksheet1["!merges"] = [{
            s: { c: 1, r: 0 },
            e: { c: 4, r: 0 }
        }];
    
        export2Excel({
            worksheets: {
                sheet1: worksheet1,
                sheet2: worksheet2
            }, // 导出excel的数据,key表示工作表名,value表示对应工作表的 sheet 数据,支持导出多个工作表
            fileName: '我的excel', // 导出文件名
            type: 'xlsx' // 文件导出类型
        });
    }
    

    三、参考资料

    • vue-json-excel插件文档
    • sheetjs-xlsx工具库
    • xlsx-style工具库

    起源地下载网 » Vue前端导出Excel文件实现方案

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元