TS 实现Excel 导出功能

本文介绍了如何使用TypeScript创建一个功能强大的导出Excel表格的工具类,包括TableHeadInfo接口定义表头,ExportExcel类处理数据导出,以及FormatCTX和相关方法如下载和生成base64字符串。

工具类:

export interface TableHeadInfo<T> {
  key: T;
  label: string
}

export interface ExportExcelParams<T extends { [key: string]: any }> {
  headInfo: TableHeadInfo<keyof T>[],
  data: T[],
  tableName: string
}

export interface FormatCTX {
  worksheet: string | 'Worksheet';
  table: string
}

export class ExportExcel<T extends { [key: string]: any }> {
  private uri: string = 'data:application/vnd.ms-excel;base64,';
  private template: string = `<html><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><body><table  border="1">{table}</table></body></html>`;

  constructor() { };
  public export(params: ExportExcelParams<T>) {
    const { headInfo, data, tableName } = params;
    const head: string = this.getHead(headInfo);
    const body: string = this.getBody(headInfo, data);
    const table: string = head + body
    this.downloadExcel(table, tableName)
  };
  //导出excel
  private downloadExcel(tableData: string, tableName: string) {
    const ctx: FormatCTX = {
      worksheet: tableName || 'Worksheet',
      table: tableData
    }
    let a: HTMLAnchorElement = document.createElement("a");
    a.href = this.uri + this.base64(this.format(ctx))
    a.download = tableName || 'excel' + '.xlsx';
    a.click();
  }
  //获取table头部信息
  private getHead(headInfo: TableHeadInfo<keyof T>[]): string {
    let head = '<tr>';
    headInfo.forEach((item, index) => {
      head += `<th style="width:200px;text-align:center;font-size:18px">${item.label}</th>`
      if (index == headInfo.length - 1) {
        head += "</tr>"
      }
    })
    return head;
  };
  //获取table内容
  private getBody(headInfo: TableHeadInfo<keyof T>[], data: ExportExcelParams<T>["data"]): string {
    let body: string = "";
    data.forEach((item) => {

      headInfo.forEach((hitem, hindex) => {
        if (hindex == 0) {
          body += '<tr>'
        }
        body += `<td style="text-align:center;font-size:18px;mso-number-format:'\@'">${(item[hitem.key] || item[hitem.key] === 0) ? item[hitem.key].toString() : ''}</td>`
        if (hindex == headInfo.length - 1) {
          body += "</tr>"
        }
      })
    })
    return body;
  };
  private format(ctx: FormatCTX): string {
    return this.template.replace(/{(\w+)}/g, function (m, p) {
      return ctx[p as keyof (FormatCTX)] as string;
    })
  };
  //转base64
  private base64(str: string): string {
    //API 将字符串转换为一个 Uint8Array 类型的数据
    const encoder = new TextEncoder();
    const data = encoder.encode(str);
    //btoa 函数只针对 Latin1 字符集
    return btoa(String.fromCharCode(...data))
  };
}

使用示例:

interface Data {
  x: string,
  y: string
}
let exportExcel = new ExportExcel<Data>()
exportExcel.export({
  headInfo: [{ key: "x", label: "X" }, { key: "y", label: "Y" }],
  data: [{ x: "1", y: "2" }],
  tableName: "坐标位置"
})
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值