react二次封装xlsx.js类实现解析和生成Excel

import XLSX from 'xlsx';

export interface Ix2jProps {
  /** 文件大小 */
  size: number;
  /** 校验文件 */
  checked: boolean;
}

export interface IxlsxJsonProps {
  /** 表头 */
  tableHead: (string | number)[];
  /** 表数据 */
  tableBody: (string | number)[][];
}

/**
 *  excel转成json数据
 * @param file
 * @param params
 */
export const xlsxToJson = (
  file: File | null,
  params: Ix2jProps = { size: 10, checked: true },
) => {
  return new Promise((resolve, reject) => {
    if (!file) {
      reject('文件不正确');
      return;
    }
    const { size, checked } = params;
    const fileName = file.name.split('.')[0],
      fileSize = file.size / 1024 / 1024,
      fileType = file.name.split('.')[1];
    if (fileSize > size) reject(`文件大小不能超过${size}M`);
    if (checked && !/(xlsx|xls)/i.test(fileType)) reject('文件格式不正确');
    const fileReader = new FileReader();
    fileReader.readAsBinaryString(file);
    fileReader.onload = (e: ProgressEvent<FileReader>) => {
      let json = e.target?.result || {};
      let workbook = XLSX.read(json, { type: 'binary' });
      let data: any[] = [];
      for (let sheet in workbook.Sheets) {
        if (workbook.Sheets.hasOwnProperty(sheet)) {
          data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
        }
      }
      resolve(data);
    };
    fileReader.onerror = () => {
      reject('转换失败');
    };
  });
};

/** 生成antd表格 */
export const json2antdTable = (xlsxList: any[]) => {
  let column: any[] = [],
    datasource: any[] = [];
  const head = xlsxList[0],
    body = xlsxList.slice(1);
  Object.entries(head).forEach(([key, val]) => {
    column.push({
      title: val,
      key,
      dataIndex: key,
    });
  });
  datasource = body.map((item) => {
    item.key = item.__rowNum__;
    Reflect.deleteProperty(item, '__rowNum__');
    return { ...item };
  });
  return {
    column,
    datasource,
  };
};

/** json转excel文件流 */
export const jsonToXlsxBlob = ({ tableHead, tableBody }: IxlsxJsonProps) => {
  const sheet = XLSX.utils.aoa_to_sheet([tableHead, ...tableBody]);
  return sheet2blob(sheet);
};

/** sheet数据转换为blob */
const sheet2blob = (sheet: XLSX.WorkSheet) => {
  function s2ab(s: any) {
    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;
  }
  const workbook = {
    SheetNames: ['sheet1'],
    Sheets: { sheet1: sheet },
  };
  const workBuf = XLSX.write(workbook, {
    bookType: 'xlsx', // 要生成的文件类型
    bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
    type: 'binary',
  });
  return new Blob([s2ab(workBuf)], { type: 'application/octet-stream' });
};

/**
 * 下载文件
 * @param blob blob文件
 * @param fileName 文件名称
 */
export const donwLoadFile = (blob: Blob, fileName: string) => {
  const url = window.URL.createObjectURL(blob);
  const aLink = document.createElement('a');
  aLink.setAttribute('href', url);
  aLink.setAttribute('download', fileName + '.xlsx');
  aLink.click();
  setTimeout(() => {
    aLink.remove();
    window.URL.revokeObjectURL(url);
  }, 300);
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值