不依赖第三方工具纯前端生成EXCEL的解决方案

·  阅读 2189
不依赖第三方工具纯前端生成EXCEL的解决方案

先说明一点本文所指的Excel其实是csv,csv是以逗号分隔值,其文件以纯文本形式存储表格数据,可以用Office或者WPS等其他工具打开,也可以把文件的后缀名csv改成xlsx这样它会更像是一个Excel。

通常来说生成Excel这个任务应该是后台来负责的,但是在前后端分离的项目中如果基于前端生成Excel这样就少了一次api请求,性能以及用户体验也会得到一定的提升,当然这只限于简单的Excel,如果数据量巨大还是采用前端生成的方案,这是不科学的,再或者说前端生成Excel比后台生成更加灵活,比如说有这样一个需求:让用户拖拽亦或者是勾选行列去生成指定内容的Excel,这种情况下前端生成的优势就体现出来了。

生成Excel的功能有很多大神已经给出来完善且强大的解决方案比如 js-xlsx,但有的时候我们的项目很小巧,引入一个js-xlsx的代码体积甚至比我们业务的代码量还要大,这是没有必要的。为了解决这一弊端我们来看怎么用原生的方法生成一个简单的Excel。

先了解一下csv的语法:

  1. 开头不留空,以行为单位。
  2. 可含或不含列名,含列名则居文件第一行。
  3. 以半角逗号作分隔符,列为空也要表达其存在。
  4. 换行用回车符表示。
  5. 特殊符号要转义,比如用来换行的回车符要用\n表示。

我们尝试把下面基于csv语法的字符串渲染成表格:
'姓名,年龄,性别,\n小红,12,男,\n小兰,13,女'

根据上面的规则把需要输出的成Excel的数据转换成符合csv语法的字符串是非常简单的,接下来看如何把这个字符串作为csv文件保存到本地。

需要下载肯定离不开a标签的download属性,可以指定a标签的download值为name.xlsx这样下载的文件就非常像是一个Excel了默认也是用Excel来打开的,接下来就只剩a标签的href属性需要处理了。

首先开头要声明data:text/csv表示是cvs文件,用\ufeff解决Excel打开中文乱码的问题,csv字符串要经过encodeURIComponent()方法的处理,下面是完整代码:

downloadExcel()
function downloadExcel(){
  let tableJson = [
    {name: '小红', phone: '123456789', address: '和阳南路'},
    {name: '小兰', phone: '123456789', address: '和阳北路'},
    {name: '小光', phone: '123456789', address: '和阳西路'},
    {name: '小明', phone: '123456789', address: '和阳东路'}
  ]
  // 第一行是标题(表头)每一列用半角逗号隔开。
  let csvStr = tableJson.map(item => {
    // 加\t是为了不让数字以科学计数法显示。
    let valueList = Object.keys(item).map(key => item[key])
    return valueList.join(',\t')
  })
  csvStr = '姓名,电话,地址,\n' + csvStr.join(',\n')

  // encodeURIComponent解决中文乱码。
  const href = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(csvStr)
  const aHtml = document.createElement('a')
  aHtml.download = 'fe_table.xlsx' // 通过修改后缀名伪装成Excel
  aHtml.href = href
  aHtml.click()
}
复制代码

分类:
前端
标签:
分类:
前端
标签: