最简单导出table为excel表格并自定义表格样式

普通方式

下包

npm i -S file-saver xlsx

在util文件夹新建类

建立to_xlsx.js

import FileSaver from 'file-saver';
import XLSX2 from 'xlsx';

class ToXlsx {
  // id指的是绑定数据的table的id,
  // title指的是导出表格的名称,记得带后缀xlsx,例如:title='重复导.xlsx';
  constructor (id, title) {
    this.id = id;
    this.title = title;
  }
  
  async createTable() {
    // 判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去,
    let fix = document.querySelector ('.el-table__fixed');
    let wb;
    if (fix) {
      wb = XLSX2.utils.table_to_book(document.querySelector(this.id).removeChild(fix));
      document.querySelector(this.id).appendChild(fix);
    } else {
      wb = XLSX2.utils.table_to_book(document.querySelector(this.id));
    }
  
    
    /* get binary string as output */
    let wBout = XLSX2.write(wb, {
      bookType: 'xlsx',
      bookSST: true,
      type: 'array'
    });
    try {
      FileSaver.saveAs(
        new Blob([wBout], {
          type: 'application/octet-stream'
        }),
        this.title
      );
    } catch (e) {
      if (typeof console !== 'undefined') console.log(e, wBout);
    }
    return wBout;
  }
}

export default ToXlsx

使用

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

import ToXlsx from "../../utils/to_xlsx";

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

参考资料

element-ui的table导出数据时重复导出

自定义样式

下包

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() {
    let sheet = XLSX2.utils.table_to_sheet(document.querySelector(this.id));
    // 设置单个单元格样式 ,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.

Style Attribute Sub Attributes Values
fill patternType "solid" or "none"
fgColor COLOR_SPEC
bgColor COLOR_SPEC
font name "Calibri" // default
sz "11" // font size in points
color COLOR_SPEC
bold true or false
underline true or false
italic true or false
strike true or false
outline true or false
shadow true or false
vertAlign true or false
numFmt "0" // integer index to built in formats, see StyleBuilder.SSF property
"0.00%" // string matching a built-in format, see StyleBuilder.SSF
"0.0%" // string specifying a custom format
"0.00%;\\(0.00%\\);\\-;@" // string specifying a custom format, escaping special characters
"m/dd/yy" // string a date format using Excel's format notation
alignment vertical "bottom" or "center" or "top"
horizontal "bottom" or "center" or "top"
wrapText true or false
readingOrder 2 // for right-to-left
textRotation Number from 0 to 180 or 255 (default is 0)
90 is rotated up 90 degrees
45 is rotated up 45 degrees
135 is rotated down 45 degrees
180 is rotated down 180 degrees
255 is special, aligned vertically
border top { style: BORDER_STYLE, color: COLOR_SPEC }
bottom { style: BORDER_STYLE, color: COLOR_SPEC }
left { style: BORDER_STYLE, color: COLOR_SPEC }
right { style: BORDER_STYLE, color: COLOR_SPEC }
diagonal { style: BORDER_STYLE, color: COLOR_SPEC }
diagonalUp true or false
diagonalDown true or false

使用

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

import ToXlsx from "../../utils/to_xlsx";

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

参考资料

使用js-xlsx纯前端导出excel

JavaScript导出excel文件,并修改文件样式

Export excel using js-xlsx pure front end

posted @ 2020-12-01 15:53  rookieM  阅读(2746)  评论(0编辑  收藏  举报