使用Sheet.JS导出表格

发布时间 2023-12-18 09:22:32作者: 夕色琉璃
前情提要:后端不想做表格导出,无奈只能自己写了,还得是配element、antd-vue,好烦呐

一个一个页面写单独的方法导出也太low了,决定封装一下

不多bb,直接上源码

utils.ts

/**
 * 导出 Excel 文件
 * @param opts 导出选项
 * @example
 * exportXlex({
 *  tableHeaderDom: document.querySelector('.a-table-box .ant-table-thead'),
 *  columns: [],
 *  dataSource: [],
 *  fileName: 'xxxx_${dayjs().format('YYYYMMDD')}.xlsx'
 */

import 'dayjs' from 'dayjs';
import * as XLSX from 'xlsx';

function exportXlex (opts: ExportXlexOptions) {
  let workbook = null;
  try {
    workbook = XLSX.utils.table_to_book(
      opts.tableHeaderDom,
      opts.table_to_book_options || { raw: true, cellDates: true }
    );
  } catch {
    workbook = XLSX.utils.book_new();
  }
  const keys = opts.columns.reduce((prev: string[], cur: column) => {
    if (cur.dataIndex) prev.push(cur.dataIndex);
    else if (cur.children) {
      cur.children.forEach((item: ColumnType) => {
        prev.push(item.dataIndex as string);
      });
    }
    return prev;
  }, []) as string[];

  const data = opts.dataSource.map((item: any) =>
    keys.map(key => {
      return isNotNullOrUndefined(item[key]?.value) ? item[key]?.value : item[key];
    })
  );
  if (workbook.Sheets.Sheet1) {
    XLSX.utils.sheet_add_aoa(workbook.Sheets.Sheet1, data, {
      origin: -1,
    });
  } else {
    workbook.SheetNames.push('Sheet1');
    workbook.Sheets.Sheet1 = XLSX.utils.aoa_to_sheet(
      data,
      opts.sheet_add_aoa_options || { origin: 0 }
    );
  }
  XLSX.writeFile(
    workbook,
    opts.fileName || `${dayjs().format('YYYYMMDDHHmmSS')}.xlsx`,
    opts.writeFileOptions || {
      bookType: 'xlsx',
    }
  );
};

type.d.ts

/**
 * 导出 Excel 文件选项
 * @param tableHeaderDom 表头dom const dom = document.querySelector('.a-table-box .ant-table-thead');
 * @param columns 列配置
 * @param dataSource 表格数据
 * @param fileName 导出文件名
 * @param table_to_book_options 表头转换配置
 * @param sheet_add_aoa_options 数据转换配置
 * @param writeFileOptions 导出配置
 */

type column = {
  dataIndex: string;
  children?: column[];
};

export interface ExportXlexOptions {
  columns: column[];
  dataSource: any[];
  tableHeaderDom?: HTMLElement | Element;
  fileName?: string;
  table_to_book_options?: object;
  sheet_add_aoa_options?: object;
  writeFileOptions?: object;
}

目前主要实现,传入列数据、表格数据,就可以导出了,其他配置可自行扩展

注意事项:

  • tableHeaderDom 传入的是表头的dom,不是表格的dom
    如果需要由于表头的dom是动态生成的,所以需要在表格渲染完成后再调用导出方法
  • 表格数据可以是请求后的数据,也可以是表格的实例,但是需要注意的是,如果是表格的实例,需要在表格渲染完成后再调用导出方法

主要是用到了sheet.jsdayjs,如果不想使用 dayjs 也可以自行修改

目前功能还不完善,后续有时间再完善吧

计划补充功能

  • 其他还咩想到...
    如果有什么好的建议,欢迎留言

欢迎转载,转载请注明出处;未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。希望能够持续的为大家带来好的技术文章,文中可能存在描述不正确的地方,欢迎指正或补充,不胜感激。