专栏首页前端技术江湖前端导出Excel实践指南

前端导出Excel实践指南

写在前面

双手奉上代码链接

https://github.com/ajun568/export-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
}

导出文件

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

结束语

开源版本不支持设置样式, 若有需求, 可采用 付费版本 或使用 xlsx-style, 使用方法与本文一致. 大家可参照文档自行添加样式部分.

参考?链接

https://github.com/SheetJS/sheetjs#writing-options

https://juejin.cn/post/6872375842358919175

http://www.seefly.top/archives/%E5%89%8D%E7%AB%AF%E4%BD%BF%E7%94%A8xlsxjs%E5%AF%BC%E5%87%BA%E6%9C%89%E5%A4%8D%E6%9D%82%E8%A1%A8%E5%A4%B4%E7%9A%84excelmd#6%E5%8D%95%E5%85%83%E6%A0%BC%E5%88%97%E5%AE%BD

关于本文

来源:黄刀小五

https://segmentfault.com/a/1190000040067999

The End

本文分享自微信公众号 - 前端技术江湖(bigerfe)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-07-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端导出Excel实践指北

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

    coder_koala
  • Vue+Element前端导入导出Excel(实践)

    arr就是我们要的结果,是一个数组。每一个值是个对象,包含了code type两个属性。

    coder_koala
  • 前端React后端Django 导出Excel

    Wyc
  • 前后端分离导出Excel

    正常导出Excel确实很简单, 前端请求接口,接口处理数据,数据处理完按成之后自动生成Excel保存到指定目录,api把文件名称,文件路径返回给前端,前端一个a...

    Wyc
  • 前端优秀实践不完全指南

    一个 Web 页面,一个 APP,想让别人用的爽,也就是所谓的良好的用户体验,我觉得他可能包括但不限于:

    Sb_Coco
  • 前端优秀实践不完全指南

    一个 Web 页面,一个 APP,想让别人用的爽,也就是所谓的良好的用户体验,我觉得他可能包括但不限于:

    桃翁
  • 前端js实现打印(导出)excel表格

    王小婷
  • 前端js实现打印(导出)excel表格

    王小婷
  • (干货)前端实现导出excel的功能

    导出功能其实在开发过程中是很常见的,平时我们做导出功能的时候基本都是后台生成,我们直接只需要调一支接口后台把生成的文件放到服务器或者数据库mongodb中,如果...

    小丑同学
  • 《DevOps实践指南》前言

    yeedomliu
  • 前端导出Excel和打印介绍

    开发后台管理系统时,都需要实现打印、导出Excel这两项功能,在前后台分离的开发模式,你是否想找一个前端解决方案。这样后端开发人员就不用为每个报表功能附加一个导...

    sam dragon
  • 微前端 qiankun 项目实践 !!! 防踩坑指南

    最近在做微前端的项目 , 过程中真是踩了不少坑 , 在有限的资料中不断试错 , 默默无语两行泪 哈哈. 在此次将采坑部分都记录下来, 让更多的人少走点弯路 ,...

    小丑同学
  • 前端-CSS变量(自定义属性)实践指南

    Sass和Less这样的预处理器,让我们的CSS代码保持良好的结构和可维护性。像变量、混合(mixins)、循环控制等特性,增强了动态编写CSS的能力,从而减少...

    grain先森
  • 记一次 微前端 qiankun 项目 实践 !!! 防踩坑指南

    最近在做微前端的项目 , 过程中真是踩了不少坑 , 在有限的资料中不断试错 , 默默无语两行泪 哈哈.  在此次将采坑部分都记录下来, 让更多的人少走点弯路 ,...

    王小婷
  • 前端框架 Rxjs 实践指北

    本文主要介绍如何在前端框架 React、Vue 使用 Rxjs,开源的 rxjs-hooks、vue-rx背后做了哪些事情。在开始之前,希望你对响应式编程、Rx...

    用户1250838
  • 前端如何将json数据导出为excel文件

    前端人员在开发时,有时为了满足用户需求,需要下载excel文件。这里通常有两种做法,一种是后端工程师将数据转化为excel,然后前端进行下载即可,还有一种方式,...

    挥刀北上
  • 基于前端JS导出Excel文件(减轻服务端压力)

    在很多OA或者CRM项目中,基本上都会涉及到Excel的导入导出的问题。 首先想到了POI和阿里的EasyExcel。 如果是小打小闹,导几千数据玩玩,服务...

    Parker
  • (码友推荐)2018-07-20 .NET及相关开发资讯速递

    8.基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势)

    Rector
  • 如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)

    最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Do...

    徐小夕

扫码关注云+社区

领取腾讯云代金券