龙空技术网

前端导出Excel在线指北

流浪的思维 171

前言:

今天咱们对“js数据导出excel”大体比较关怀,我们都需要学习一些“js数据导出excel”的相关知识。那么小编也在网络上网罗了一些对于“js数据导出excel””的相关资讯,希望姐妹们能喜欢,各位老铁们一起来学习一下吧!

奉上最终效果图

观前提醒

本文最终实现效果如上图, 具体功能为: 导出Excel + 多个Sheet + 可合并的多行表头. 代码部分采用 React+TS 作为工具进行编写.

准备工作

安装 xlsx.js npm install xlsx

写入Excel文件: XLSX.write(workbook, writeOpts)

workbook

SheetNames @types string[]: 当前 Sheet 的名称Sheets: 当前sheet的对象, 格式如下

[SheetNames]: {  "!refs": "A1:G7", // 表示从 第1行第A列 到 第7行第G列  "!cols": [{wpx: 80} ... ], // 表示 列宽 80px  "!rows": [{hpx: 20} ... ], // 表示 行高 20px  "!merges": [{s: {r: 0, c: 2}, e: {r: 0, c: 3}} ... ], // 表示 将 第0行第2列 和 第0行第3列 进行合并 (s: start, e: end, c: column, r: row)  "A1": {v: "姓名"}, // 表示第1行第A列 显示数据为 "姓名", 以此类推 ...  ...}

writeOpts

{  type, // 数据编码, 本文采用 binary 二进制格式  bookType, // 导出类型, 本文采用 xlsx 类型  compression, // 是否使用 Gzip 压缩}
下载文件

想要下载文件, 我小A第一个表示不服, 申请出战 <a 标签的 download 属性>

通过 URL.createObjectURL(Object) 来创建下载所需的 URL. 由于每次调用都会产生新的 URL 对象, 故使用后记得释放, 释放方法 URL.revokeObjectURL(FileUrl)

通过模拟 click 事件触发 a 标签, 以实现下载

const saveAs = (obj: Blob, fileName?: string): void => {  const temp = document.createElement('a')  temp.download = fileName || 'download'  temp.href = URL.createObjectURL(obj)  temp.click()  setTimeout(() =>  { URL.revokeObjectURL(temp.href) }, 100)}
头部处理

Mock数据: 详细数据请跳转 Github, 在 mock.ts 中查看

Header 部分数据格式

[  ...  {    key: 'animal',    value: '动物',    child: [      {        key: 'dog',        value: '狗',        child: [          {            key: 'corgi',            value: '柯基',          },          {            key: 'husky',            value: '哈士奇',          },        ],      },      {        key: 'tiger',        value: '老虎',      },    ],  },  ...]

Data 部分数据格式

[  {    name: '黄刀小五',    desc: '基于搜索引擎的复制粘贴攻城狮',    watermelon: '喜欢',    banana: '不喜欢',    corgi: '喜欢',    husky: '喜欢',    tiger: '不喜欢',  },  ...]
头部数据处理

分析

Header 数据为树形结构, 其深度为头部所占行数Header 数据要转换成 Data 数据的格式, 并与 Data 数组合并, 共同处理成导出所需格式转换对象的 key 应为最小叶子结点的 key转换对象的 value 应为当前层级的 value ( 即导出后当前行所显示的 value )既然是树, 果断递归, 准没错

‍♂️ Code

‍♂️ Image

Merged 数据

{  s: { // start    r: x, // row    c: y, // column  },  e: { ... } // end}

分析

将处理后的头部数据看成一个矩阵行或列中, 相邻元素若相同, 则进行合并

tips: 本文采用的是判断相邻 value 值是否相等进行合并, 若有需求, 建议改写为对象形式加以完善.

‍♂️ Code

‍♂️ Image

生成sheet数据利用Object.assign进行对象合并利用String.fromCharCode(65 + i)对列进行大写字母的转换

‍♂️ Code

‍♂️ Image

转换字节流

利用 new ArrayBuffer(str) 创建一个缓冲区, 使用 new Uint8Array(buf) 引用

因为 unicode 编码是 0~65535, 而 Uint8Array 范围为 0~255, 故需要按位与 0xFF, 以保持位数一致

const s2ab = (str: string): ArrayBuffer => {  let buf = new ArrayBuffer(str.length)  let view = new Uint8Array(buf)  for (let i = 0; i !== str.length; ++i) {    view[i] = str.charCodeAt(i) & 0xFF  }  return buf}
导出文件

结合前文 准备工作 部分所讲, 导出的代码逻辑就出来了, 直接上代码

标签: #js数据导出excel