vue xlsx表单导出样式设置

参考:https://www.cnblogs.com/liuxianan/p/js-excel.html

注意:博客代码是没有整理直接从原代码中复制的,看不懂的查看视频,或者直接下载dome代码查看。

视频:https://live.csdn.net/v/146981

demo代码:https://download.csdn.net/download/weixin_35773751/14927955


1. xlsx 开发手册

https://github.com/SheetJS/sheetjs#installation

2. xlsx 中文手册

https://segmentfault.com/a/1190000018077543

3. xlsx-style 手册

https://www.npmjs.com/package/xlsx-style

3. Blob、ArrayBuffer和Buffer

https://zhuanlan.zhihu.com/p/97768916

前面是要掌握的知识点,不要求全懂但是得知道到底要干什么。

4. 业务代码

前言:我是在项目中的全局方法库文件开发的,所以这里是直接在全局方法库文件中开发。

首先,引入xlsxxlsx-style

import * as XLSX from 'xlsx' // XLSX 表单导出
import { write } from "xlsx-style"; // lsx-style 表单样式

备注:这里我只要xlsx-style中的write就够了。

安装结束报错./cptable in ./node_modules/_xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js

解决办法:
在\node_modules\xlsx-style\dist\cpexcel.js 807行 的 var cpt = require(’./cpt’ + ‘able’); 改成 var cpt = cptable;

如图:
在这里插入图片描述

然后,制作导出方法:

export function fileExport3(selectData, dataListCall, fileName){
    
    if(selectData && selectData.length > 0){
        selectData = nullClear(selectData) // 清除数据中的null

        selectData = JSON.parse(JSON.stringify(selectData))

        dataListCall = JSON.parse(JSON.stringify(dataListCall)) // 深拷贝数据

        let data = formatExcelData(selectData, dataListCall) // 格式化选中数据,将字典数据解析成汉字

        let sheet = XLSX.utils.aoa_to_sheet(data); // 官方工具类,将一个二维数组转成sheet数据

        let flName = JSON.parse(JSON.stringify(fileNameFun(fileName))) // 格式化文件名称为,日期 + 时间 + 当前菜单 + 文件类型

        // sheet['!merges'] = [ // 合并
        //     {
        //         s: {r: 0, c: 0}, 
        //         e: {r: 0, c: 2}
        //     }
        // ];

        // sheet['!cols'] = [ // 宽度
        //     { wpx: 500 },
        // ]

        sheet = excelStyle(sheet) // 定义表格样式

        if (!timer) { // 节流
            timer = setTimeout(() => {
                Elements.Message.success(Zh.exportSuccess)
                openDownloadDialog(sheet2blob(sheet), flName); // 导出文件
                timer = null
            }, 500)
        }
    }else{
        Elements.Message.warning(Zh.exportData)
    }
}

这里要注意:xlsx 是支持合并的(例如注销的合并部分),但不支持样式。网上资料说有个pro版本是可以的,但是要付费,所以我们就用开源的xlsx-style来实现样式。

然后,我还需要一个下载方法:

/**
 * 下载对话框
 * @param url 下载地址,也可以是一个blob对象,必选
 * @param saveName 文件名,可选
*/
function openDownloadDialog(url, saveName) {
    if (typeof url == 'object' && url instanceof Blob) {
        url = URL.createObjectURL(url); // 创建blob地址
    }
    var aLink = document.createElement('a');
    aLink.href = url;
    aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:// 模式下不会生效
    var event;
    if (window.MouseEvent) event = new MouseEvent('click');
    else {
        event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    }
    aLink.dispatchEvent(event);
}

而我在下载的时候还需要加一个sheet数据转excel文件流的方法:

/**
 * sheet数据转excel文件的数据,然后利用URL.createObjectURL下载
 * sheet  sheet数据
 * sheetName  文件名称
*/
function sheet2blob(sheet, sheetName) {
    sheetName = sheetName || '导出文件'; // 文件名不存在,默认为‘导出文件’

    var workbook = {
        SheetNames: [sheetName],
        Sheets: {}
    };
    console.log(workbook,'workbook')

    workbook.Sheets[sheetName] = sheet;

    var wopts = { // excel配置
        bookType: 'xlsx', // 要生成的文件类型
        bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
        type: 'binary'
    };

    // var wbout = XLSX.write(workbook, wopts); // 将表格数据转成文档流
    var wbout = write(workbook, wopts); // 将表格数据转成文档流
    // console.log(wbout,'wbout++')

    var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" }); // 转成Blob数据
    
    function s2ab(s) { // 字符串转ArrayBuffer
        var buf = new ArrayBuffer(s.length); // 二进制缓冲区

        var view = new Uint8Array(buf); // 

        for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;

        return buf;
    }

    return blob;
}

到这里那就所以逻辑就都写完了,我们只需要在要使用的地方调用就ok了。

效果图:
在这里插入图片描述
在这里插入图片描述

完美。(* ̄︶ ̄)

posted @ 2022-12-06 22:19  轻风细雨_林木木  阅读(385)  评论(0编辑  收藏  举报