• 前端用xlsx实现导出表格数据到excel的功能


    之前做导出表格功能时,都是后端进行实现,最近,领导要求前端实现导出,经过一番查找资料终于实现。

    普通方式

    下包

    npm i -S file-saver xlsx
    

    在util文件夹新建类

    建立to_xlsx.js

     1 import FileSaver from 'file-saver';
     2 import XLSX2 from 'xlsx';
     3 
     4 class ToXlsx {
     5   // id指的是绑定数据的table的id,
     6   // title指的是导出表格的名称,记得带后缀xlsx,例如:title='重复导.xlsx';
     7   constructor (id, title) {
     8     this.id = id;
     9     this.title = title;
    10   }
    11   
    12   async createTable() {
    13
        // 判断要导出的节点中是否有fixed的表格,如果有,转换excel时将该dom移除
          let table = document.querySelector(this.id).cloneNode(true);
          let fix = table.querySelector(".el-table__fixed");
          let fix_left = table.querySelector(".el-table__fixed-left");
          let fix_right = table.querySelector(".el-table__fixed-right");

          fix && table.removeChild(fix);
          fix_left && table.removeChild(fix_left);
          fix_right && table.removeChild(fix_right);
          let wb;
          wb = XLSX2.utils.table_to_book(table);
    22   
    23     
    24     /* get binary string as output */
    25     let wBout = XLSX2.write(wb, {
    26       bookType: 'xlsx',
    27       bookSST: true,
    28       type: 'array'
    29     });
    30     try {
    31       FileSaver.saveAs(
    32         new Blob([wBout], {
    33           type: 'application/octet-stream'
    34         }),
    35         this.title
    36       );
    37     } catch (e) {
    38       if (typeof console !== 'undefined') console.log(e, wBout);
    39     }
    40     return wBout;
    41   }
    42 }
    43 
    44 export default ToXlsx

    使用

    在js页面直接import,然后使用

    import ToXlsx from "../../utils/to_xlsx";
    
    // 参数1 表格id
    // 参数2 保存的excel文件名
    let xlsx = new ToXlsx('#table-data', '下载.xlsx');
    xlsx.createNormalTable()

    自定义样式

    下包

    npm i -S xlsx-style xlsx

    xlsx-style报错修改

    个时候需要修改源码

    在\node_modules\xlsx-style\dist\cpexcel.js 807行把 var cpt = require('./cpt' + 'able'); 改成 var cpt = cptable;

    如果还报错 在\node_modules\xlsx-style\ods.js 10行和13行把路径改为 require('./ xlsx')

    在util文件夹新建类

    建立to_xlsx.js

    import XLSX2 from 'xlsx';
    import XLSX from 'xlsx-style';
    
    class ToXlsx {
      // id指的是绑定数据的table的id,
      // title指的是导出表格的名称,记得带后缀xlsx,例如:title='重复导.xlsx';
      constructor (id, title) {
        this.id = id;
        this.title = title;
      }
      
      /**
       * 自定义表格
       * @returns {Promise<void>}
       */
      async createCustomizeTable() {
      
       // 判断要导出的节点中是否有fixed的表格,如果有,转换excel时将该dom移除
        let table = document.querySelector(this.id).cloneNode(true);
        let fix = table.querySelector(".el-table__fixed");
        let fix_left = table.querySelector(".el-table__fixed-left");
        let fix_right = table.querySelector(".el-table__fixed-right");

        fix && table.removeChild(fix);
        fix_left && table.removeChild(fix_left);
        fix_right && table.removeChild(fix_right);
    
        let sheet = XLSX2.utils.table_to_sheet(table);
        // 设置单个单元格样式 ,A2对应的是excel表格的A2
        // sheet["A2"].s = {
        //   alignment: {
        //     horizontal: "center",
        //     vertical: "center",
        //     wrap_text: true
        //   }
        };
        
        // sheet居然是个对象,所以遍历就用for in
        // 偷个懒,因为要所有的表格都居中,所以这里就用for in 遍历设置了,如果只是单个设置,那就用上面的单独设置就行
        for (let key in sheet){
          if (new RegExp('^[A-Za-z0-9]+$').exec(key)) {
            let cell = key.toString();
            sheet[cell].s = {
              alignment: {
                horizontal: "center", // 水平对齐-居中
                vertical: "center", // 垂直对齐-居中
                wrap_text: true
              }
            }
          }
        }
        
        // wpx 字段表示以像素为单位,wch 字段表示以字符为单位
        // 注意,必须从第一个开始设置,不能只设置单独一个
        // !cows是列宽
        sheet['cols'] = [
              {wch: 16}, // A列
              {wch: 16}, // B列
              {wch: 16}, // C列
              {wch: 16}, // D列
        ];
       
        // !rows设置的行高
        sheet['!rows'] = [
              {wpx: 40,}, // 1行
              {wpx: 40}, // 2行
              {wpx: 40}, // 3行
              {wpx: 40}, // 4行
        ];
        try {
          this.openDownloadDialog(this.sheet2blob(sheet), this.title);
        } catch (e) {
         console.log('自定义表格报错', e);
        }
      }
      
      /**
       * 将表转换为最终excel文件的blob对象,并使用URL.createObjectUR下载它
       * @param sheet 表格配置项
       * @param sheetName 表格名称
       * @returns {Blob}
       */
      sheet2blob(sheet, sheetName) {
        sheetName = sheetName || 'sheet1';
        let workbook = {
          SheetNames: [sheetName],
          Sheets: {}
        };
        workbook.Sheets[sheetName] = sheet; // 生成excel的配置项
        
        let wopts = {
          bookType: 'xlsx', // 要生成的文件类型
          bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
          type: 'binary'
        };
        let wbout = XLSX.write(workbook, wopts);
        let blob = new Blob([s2ab(wbout)], {
          type: "application/octet-stream"
        }); // 字符串转ArrayBuffer
        
        function s2ab(s) {
          let 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;
        }
        return blob;
      }
      
      /**
       *
       * @param url 生成的文件
       * @param saveName 保存文件名称
       */
      openDownloadDialog(url, saveName) {
        if (typeof url == 'object' && url instanceof Blob) {
          url = URL.createObjectURL(url); // 创建blob地址
        }
        let aLink = document.createElement('a');
        aLink.href = url;
        aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
        let 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);
      }
    }
    
    export default ToXlsx

    单元格样式

    设置单元格的样式,就是设置工作表对象中的单元格对象的 s 属性。这个属性的值也是一个对象,它有五个属性:fill、font、numFmt、alignment和border。

    Cell styles are specified by a style object that roughly parallels the OpenXML structure. The style object has five top-level attributes: fill, font, numFmt, alignment, and border.

    使用

    在js页面直接import,然后使用

    import ToXlsx from "../../utils/to_xlsx";
    
    // 参数1 表格id
    // 参数2 保存的excel文件名
    let xlsx = new ToXlsx('#table-data', '下载.xlsx');
    xlsx.createCustomizeTable()
  • 相关阅读:
    项目实战【vue,react,微信小程序】(1708E)
    java——集合——List集合——List集合
    java——集合——List集合——LinkedList集合
    Java——集合——泛型——泛型通配符
    Java——集合——泛型——定义和使用含有泛型的接口
    java——集合——List集合——ArrayList集合
    工作效率
    js中__proto__和prototype的区别和关系?
    KubeEdge架构问题汇总
    整数分解
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/16279889.html
Copyright © 2020-2023  润新知