js 导出 excel (js-xlsx)

1,104 阅读1分钟

最近项目有一个需求就是需要将一个表格导出 excel 文件,在网上找了一圈,通过实践得到的方法,记录一下。闲话少说,直接上代码(最后有完整代码,建议直接到底复制试用,然后根据自己需求修改)

首先先用表格元素将你要导出的数据按照实际需求渲染出来,这里我就简单的写一个表格作为例子

<table id="table" border style="border-collapse: collapse; width: 20%; text-align: center;">
    <tr>
      <td>表头1</td>
      <td>表头2</td>
      <td>表头3</td>
    </tr>
    <tr>
      <td>数据1-1</td>
      <td>数据1-2</td>
      <td>数据1-3</td>
    </tr>
    <tr>
      <td>数据2-1</td>
      <td>数据2-2</td>
      <td>数据2-3</td>
    </tr>
    <tr>
      <td>数据3-1</td>
      <td>数据3-2</td>
      <td>数据3-3</td>
    </tr>
  </table>

如下图所示

image.png

接着,我们导入 js-xlsx

<script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

定义 sheet2blob 方法,该方法的作用是将一个 sheet 文件转换为 blob 对象

function sheet2blob(sheet, sheetName) {
  sheetName = sheetName || 'sheet1'
  var workbook = {
    SheetNames: [sheetName],
    Sheets: {}
  }
  workbook.Sheets[sheetName] = sheet // 生成excel的配置项

  var wopts = {
    bookType: 'xlsx', // 要生成的文件类型
    bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
    type: 'binary'
  }
  var wbout = XLSX.write(workbook, wopts)
  var blob = new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }) // 字符串转ArrayBuffer
  function s2ab(s) {
    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
  }
  return blob
}

接着定义 downloadExcel 方法,该方法接收要导出的 dom 节点,然后先将节点转换为 sheet 对象,接着在转换为 blob 对象,最终通过 URL.createObjectURL 转换为可以下载的 url 字符串

function downloadExcel (dom, filename) {
  filename = filename ? filename : moment().format('YYMMDDHHmm')
  const sheet = XLSX.utils.table_to_sheet(dom)
  const blob = sheet2blob(sheet)
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = `${filename}.xlsx`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

最后,我们添加一个下载按钮,绑定一个 toExcel 事件导出我们所需要的 excel 文件

function toExcel () {
  const dom = document.getElementById('table')
  downloadExcel(dom, 'excel.xlsx')
}

最终的完整代码如下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Comfible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <table id="table" border style="border-collapse: collapse; width: 20%; text-align: center;">
    <tr>
      <td>表头1</td>
      <td>表头2</td>
      <td>表头3</td>
    </tr>
    <tr>
      <td>数据1-1</td>
      <td>数据1-2</td>
      <td>数据1-3</td>
    </tr>
    <tr>
      <td>数据2-1</td>
      <td>数据2-2</td>
      <td>数据2-3</td>
    </tr>
    <tr>
      <td>数据3-1</td>
      <td>数据3-2</td>
      <td>数据3-3</td>
    </tr>
  </table>
  <button onclick="toExcel()">导出excel</button>
  <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
  <script>
    // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
    function sheet2blob(sheet, sheetName) {
      sheetName = sheetName || 'sheet1'
      var workbook = {
        SheetNames: [sheetName],
        Sheets: {}
      }
      workbook.Sheets[sheetName] = sheet // 生成excel的配置项

      var wopts = {
        bookType: 'xlsx', // 要生成的文件类型
        bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
        type: 'binary'
      }
      var wbout = XLSX.write(workbook, wopts)
      var blob = new Blob([s2ab(wbout)], {
        type: "application/octet-stream"
      }) // 字符串转ArrayBuffer
      function s2ab(s) {
        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
      }
      return blob
    }

    function downloadExcel (dom, filename) {
      filename = filename ? filename : moment().format('YYMMDDHHmm')
      const sheet = XLSX.utils.table_to_sheet(dom)
      const blob = sheet2blob(sheet)
      const url = URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = `${filename}.xlsx`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }

    function toExcel () {
      const dom = document.getElementById('table')
      downloadExcel(dom, 'excel.xlsx')
    }
  </script>
</body>
</html>