首页 > 其他分享 >vue前端根据el-table导出excel

vue前端根据el-table导出excel

时间:2024-03-28 10:26:57浏览次数:31  
标签:el style vue wb xlsx excel len let elt

1.导入xlsx、xlsx-style、file-saver

npm install --save xlsx
npm install --save xlsx-style
npm install --save file-saver

2.防止xlsx-style报错 vue.config.js添加

chainWebpack(config) {
    config.externals({ "./cptable": "var cptable" }); // xlsx-style 
}

3.编写utils

import * as XLSX from "xlsx";
import XLSXStyle from "xlsx-style";
import { saveAs } from "file-saver";
/**
 *
 * @param elt 
 * @param sheetName 内部sheet名称
 * @param fileName 导出的文件名
 * @param titleNum  标题行数
 */
export function exportTable(elt, sheetName, fileName, titleNum) {
    const xlsxParam = { sheet: sheetName, raw: true };
    const fix = elt.querySelector(".el-table__fixed"); //如果是都给了fixed样式
    let wb;
    if (fix) {
        //判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去
        wb = XLSX.utils.table_to_book(elt.removeChild(fix), xlsxParam);
        elt.appendChild(fix);
    } else {
        wb = XLSX.utils.table_to_book(elt, xlsxParam);
    }
    // let wb = XLSX.utils.table_to_book(elt, { sheet: sheetName, raw: true });
    let range = XLSX.utils.decode_range(wb.Sheets[sheetName]["!ref"]);
    //单元格边框样式
    let borderStyle = {
        top: {
            style: "thin",
            color: { rgb: "000000" },
        },
        bottom: {
            style: "thin",
            color: { rgb: "000000" },
        },
        left: {
            style: "thin",
            color: { rgb: "000000" },
        },
        right: {
            style: "thin",
            color: { rgb: "000000" },
        },
    };
    let cWidth = [];
    for (let C = range.s.c; C <= range.e.c; ++C) {
        //SHEET列
        let len = 100; //默认列宽
        let len_max = 400; //最大列宽
        for (let R = range.s.r; R <= range.e.r; ++R) {
            //SHEET行
            let cell = { c: C, r: R }; //二维 列行确定一个单元格
            let cell_ref = XLSX.utils.encode_cell(cell); //单元格 A1、A2
            if (wb.Sheets[sheetName][cell_ref]) {
                // if (R == 0){
                if (R < titleNum) {
                    wb.Sheets[sheetName][cell_ref].s = {
                        //设置第一行单元格的样式 style
                        font: {
                            // sz: 15,
                            color: { rgb: "060B0E" },
                            bold: true,
                        },
                        alignment: {
                            horizontal: "center",
                            vertical: "center",
                        },
                        fill: {
                            fgColor: { rgb: "E4E4E4" },
                        },
                        border: borderStyle, //用上面定义好的边框样式
                    };
                } else {
                    wb.Sheets[sheetName][cell_ref].s = {
                        alignment: {
                            horizontal: "center",
                            vertical: "center",
                        },
                        border: borderStyle, //用上面定义好的边框样式
                    };
                }
                //动态自适应:计算列宽
                let va = JSON.parse(
                    JSON.stringify(wb.Sheets[sheetName][cell_ref].v)
                );
                var card1 = JSON.parse(JSON.stringify(va)).match(
                    /[\u4e00-\u9fa5]/g
                ); //匹配中文
                var card11 = "";
                if (card1) {
                    card11 = card1.join("");
                }
                var card2 = JSON.parse(JSON.stringify(va)).replace(
                    /([^\u0000-\u00FF])/g,
                    ""
                ); //剔除中文
                let st = 0;
                if (card11) {
                    // st += card11.length * 16  //中文字节码长度
                    st += card11.length * 20; //中文字节码长度
                }
                if (card2) {
                    // st += card2.length * 8  //非中文字节码长度
                    st += card2.length * 10; //非中文字节码长度
                }
                if (st > len) {
                    len = st;
                }
            }
        }
        if (len > len_max) {
            //最大宽度
            len = len_max;
        }
        cWidth.push({ wpx: len }); //列宽
    }
    wb.Sheets[sheetName]["!cols"] = cWidth;
    var wopts = { bookType: "xlsx", bookSST: false, type: "binary" };
    var wbout = XLSXStyle.write(wb, wopts); //一定要用XLSXStyle不要用XLSX,XLSX是没有格式的!
    saveAs(new Blob([s2ab(wbout)], { type: "" }), fileName + ".xlsx");
}
function s2ab(s) {
    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;
}

4.引用

let elt = document.getElementById("educe-table");
exportTable(elt, "小题分统计", "小题分统计导出", 3)

 

标签:el,style,vue,wb,xlsx,excel,len,let,elt
From: https://www.cnblogs.com/wjian0916/p/18100937

相关文章

  • 部署elementPlus离线版本
    最近项目需要离线开发,不能联网查一些组件的api,于是决定搞一个离线版的文档一、下载官方文档下载地址github地址gitee地址选择版本直接下载压缩包二、下载live-server插件全局下载live-server插件npmilive-server-gvscode下载三、运行在文件目录下......
  • 【Vue】 签名组件
    一、需求背景:检查业务,检查完成后,执行人需要签字证明检查完成 二、实现效果: 三、技术实现通过canvas转换成blob对象,可以上传到文件服务,或者是下载另存为到本地磁盘注意重点,canvas的样式的宽高和dom对象宽高一定要一致才可以,否则无法在面板绘制线条!<template><el-dia......
  • 基于PHP+vue的社区居民互助交流系统016gm
    。开发环境开发语言:php后端框架:Thinkphp/Laravel前端框架:vue.js服务器:apache数据库:mysql运行环境:phpstudy/wamp/xammp等社区互助平台的功能分为管理员和用户两个部分,系统的主要功能包括首页,个人中心,用户管理,租房信息管理,失物招领管理,宠物代遛管理,停车位出租管理,其他管......
  • Thinkphp/Laravel校园二手书交易系统oc81w
     开发语言:php后端框架:Thinkphp/Laravel前端框架:vue.js服务器:apache数据库:mysql运行环境:phpstudy/wamp/xammp等 性能非的功能分为管理员,卖家用户和用户三个部分,系统的主要功能包括首页、个人中心、用户管理、卖家用户管理、图书分类管理、二手图书管理、求购图书管理、......
  • 基于SpringBoot+Vue的在线家具商城毕业设计
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 基于SpringBoot+Vue的新冠病毒密接者跟踪系统毕业设计
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 解决 TS7053: Element implicitly has an any type because expression of type strin
    背景有个接口interfaceDataType{id:number;name:string;created_at:string;updated_at:string;}我的数据{"id":9,"created_at":"2024-03-11T17:50:16.129235+08:00","updated_at":"202......
  • vue3背景下,el-input嵌套在弹出框中,自动聚焦“失效”?如何实现自动聚焦
    情景:在一个弹出框中,有一个el-input输入框,想要实现当弹出框出现时,input会自动聚焦。使用input的原生属性autofocus去自动获取焦点失效;使用ref获取el-input元素也显示undefined!!!<el-dialogv-model="dialogFormVisible"width="300">.......<el-input......
  • 解决element-ui el-select数据过大方案
    一、背景项目中需要用到el-select选择医院,全国医院数据量非常大,通过API读取数据页面直接卡死。 二、解决方案1、组件:el-select+vue虚拟滚动(vue-virtual-scroll-list)2、安装:npminstallvue-virtual-scroll-list--save3、参考:NPM地址:https://www.npmjs.com/pack......
  • 各种 IntelliJ IDEA 酷炫插件推荐
    (2)BackgroundImagePlusidea背景修改插件,让你的idea与众不同,可以设置自己喜欢的图片作为code背景。安装成功之后重启,菜单栏的VIew标签>点击SetBackgroundImage(没安装插件是没有这个标签的),在弹框中路由选择到本地图片,点击OK即可。(3)Grepconsole自定义日志颜色,idea控......