利用 xlsx 实现JS自定义导出excel表格

xlsx 包介绍 npm

准备步骤:引入资源

<script lang="javascript" src="dist/xlsx.full.min.js"></script>

封装方法库

// 字符串转字符流
function s2ab(s) {
  const buf = new ArrayBuffer(s.length);
  const view = new Uint8Array(buf);
  for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
  return buf;
}

/**
 * 将 js 对象的数组转换为工作表。
 * @param {string[]} header - 表头
 * @param {Object} headerDisplay - 表头名称
 * @param {object[]} sheetData - 表数据
 * @param {Boolean} skipHeader - 是否隐藏表头
 * @returns 工作表
 */
function jsonToSheet(header, headerDisplay, sheetData, skipHeader) {
  const newSheetData = skipHeader ? [headerDisplay, ...sheetData] : sheetData;
  const ws = window.XLSX.utils.json_to_sheet(newSheetData, {
    header,
    skipHeader,
  });

  return ws;
}

/**
 * 自定义将js数据导出下载excel
 * 
 * sheetHeaderDisplay(表头名称) 不存在时,默认使用 sheetHeader(表头key) 当做表头名称
 * @param {Object[]} data - 所有表信息
 * @param {string} data[].sheetName - 表名称
 * @param {string[]} data[].sheetHeader - 表头key
 * @param {Object} data[].sheetHeaderDisplay - 表头名称
 * @param {Object[]} data[].sheet - 表数据
 * @param {string} excelName - 导出的excel名称
 * @example 
  [
    {
      sheetName: 'Tom and Jerry',
      sheetHeader: ['name', 'age', 'sex'],
      sheetHeaderDisplay: {name: '名字', age: '年龄', sex: '性别'},
      sheet: [
        { name: 'Tom', age: 3, sex: '男' },
        { name: 'Jerry', age: 2, sex: '女' },
        { name: 'Spike', age: 4, sex: '男' },
      ],
    },
  ];
 */
function Xlsx(data, excelName) {
  const tmpWB = {
    SheetNames: [], // 保存的表标题
    Sheets: {}, // 表数据
  };

  // 生成excel的配置项
  data.forEach(item => {
    const skipHeader =
      Object.prototype.toString.call(item.sheetHeaderDisplay) === '[object Object]' && Object.keys(item.sheetHeaderDisplay).length > 0;
    tmpWB.SheetNames.push(item.sheetName);
    tmpWB.Sheets[item.sheetName] = Object.assign({}, jsonToSheet(item.sheetHeader, item.sheetHeaderDisplay, item.sheet, skipHeader), {});
  });

  // 创建二进制对象写入转换好的字节流
  const tmpDown = new Blob(
    [
      s2ab(
        // write 用来把数据写入并生成 xlsx 文件的 API
        window.XLSX.write(
          tmpWB,
          {
            // 要生成的文件类型: 'xlsx'|'xlsm'|'xlsb'
            bookType: 'xlsx',
            bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
            type: 'binary',
          }, // 这里的数据是用来定义导出的格式类型
        ),
      ),
    ],
    {
      type: '',
    },
  );

  const outFile = document.createElement('a');
  const href = URL.createObjectURL(tmpDown); // 创建对象超链接
  outFile.download = `${excelName || 'export'}.xlsx`; // 下载名称
  outFile.style.display = 'none';
  outFile.href = href; // 绑定a标签
  document.body.appendChild(outFile);
  outFile.click(); // 模拟点击实现下载
  setTimeout(() => {
    // 延时释放
    URL.revokeObjectURL(tmpDown); // 用URL.revokeObjectURL()来释放这个object URL
    document.body.removeChild(outFile);
  }, 100);
}

export default Xlsx;

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐