使用 XLSX.js 导出 Excel 文件

文章目录

在前端开发中,经常会遇到 将页面表格数据导出为 Excel 文件 的需求,例如:

  • 后台管理系统数据导出
  • 报表下载
  • 用户数据备份

本文介绍如何使用 XLSX.js 将 HTML 表格数据导出为 .xlsx 文件。

一、实现效果

点击按钮后,将页面中的表格数据导出为 Excel 文件。

示例效果:

二、引入 XLSX.js

下载 xlsx.core.min.js:

复制代码
https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js

也可以直接通过 CDN 引入:

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js"></script>

三、HTML 表格结构

首先准备一个简单的 HTML 表格。

html 复制代码
<table id="myTable">
  <thead>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>手机号</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>范闲</td>
      <td>18</td>
      <td>188888888888</td>
    </tr>
    <tr>
      <td>范健</td>
      <td>38</td>
      <td>138888888888</td>
    </tr>
  </tbody>
</table>

<button onclick="export_table_to_excel('myTable')">
  导出
</button>

四、核心导出逻辑

点击按钮时调用 export_table_to_excel 方法,实现 Excel 导出。

javascript 复制代码
function export_table_to_excel(id) {
  const table = document.getElementById(id)

  const result = generateArray(table)
  const data = result[0]
  const ranges = result[1]

  const wb = new Workbook()
  const ws = sheet_from_array_of_arrays(data)

  ws["!merges"] = ranges

  const wsName = "Sheet1"

  wb.SheetNames.push(wsName)
  wb.Sheets[wsName] = ws

  const wbout = XLSX.write(wb, {
    bookType: "xlsx",
    type: "binary"
  })

  const blob = new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  })

  const a = document.createElement("a")

  a.href = URL.createObjectURL(blob)
  a.download = "table.xlsx"

  a.click()

  URL.revokeObjectURL(a.href)
}

五、核心实现思路

整个导出流程主要分为 5 个步骤:

1 获取表格数据

通过 document.getElementById 获取 HTML table。

javascript 复制代码
const table = document.getElementById("myTable")

2 解析表格数据

将表格转换为 二维数组。

复制代码
[
  ["姓名","年龄","手机号"],
  ["范闲",18,"188888888888"],
  ["范健",38,"138888888888"]
]

3 生成 Worksheet

使用二维数组生成 Excel 的 worksheet。

javascript 复制代码
const ws = sheet_from_array_of_arrays(data)

4 创建 Workbook

Excel 文件本质上是 Workbook(工作簿) + Worksheet(工作表)。

复制代码
Workbook
 └── Worksheet
      └── Table Data

5 生成并下载 Excel

通过 XLSX.write 生成 Excel 二进制数据,再通过 Blob 下载。

javascript 复制代码
const blob = new Blob([s2ab(wbout)])

六、导出流程图

复制代码
HTML Table
    │
    ▼
解析 Table 数据
(generateArray)
    │
    ▼
生成二维数组
    │
    ▼
生成 Worksheet
(sheet_from_array_of_arrays)
    │
    ▼
创建 Workbook
    │
    ▼
XLSX.write 生成 Excel
    │
    ▼
Blob 下载文件

七、完整示例代码

完整示例代码如下:

html 复制代码
<!DOCTYPE html>
<html>
<head>
<title>HTML Template</title>
<style>
table{
border-collapse: collapse;
}

th,td{
border:1px solid #000;
}
</style>
</head>

<script src="./xlsx.core.min.js"></script>

<body>

<table id="myTable">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>手机号</th>
</tr>
</thead>

<tbody>
<tr>
<td>范闲</td>
<td>18</td>
<td>188888888888</td>
</tr>

<tr>
<td>范健</td>
<td>38</td>
<td>138888888888</td>
</tr>

<tr>
<td>范无咎</td>
<td>30</td>
<td>130000000000</td>
</tr>

<tr>
<td>范若若</td>
<td>18</td>
<td>188888888888</td>
</tr>

</tbody>
</table>

<button onclick="export_table_to_excel('myTable')">
导出
</button>

<script>

function export_table_to_excel(id){

var theTable=document.getElementById(id)

var oo=generateArray(theTable)

var ranges=oo[1]

var data=oo[0]

var ws_name="SheetJS"

var wb=new Workbook(),
ws=sheet_from_array_of_arrays(data)

ws["!merges"]=ranges

wb.SheetNames.push(ws_name)

wb.Sheets[ws_name]=ws

var wbout=XLSX.write(wb,{
bookType:"xlsx",
bookSST:false,
type:"binary"
})

const newBlob=new Blob([s2ab(wbout)],{
type:"application/octet-stream"
})

let fileName="test.xlsx"

var a=document.createElement("a")

var url=window.URL.createObjectURL(newBlob)

a.href=url

a.download=fileName

a.click()

window.URL.revokeObjectURL(url)

}

function generateArray(table){

var out=[]
var rows=table.querySelectorAll("tr")
var ranges=[]

for(var R=0;R<rows.length;++R){

var outRow=[]
var row=rows[R]
var columns=row.querySelectorAll("td")

for(var C=0;C<columns.length;++C){

var cell=columns[C]
var colspan=cell.getAttribute("colspan")
var rowspan=cell.getAttribute("rowspan")
var cellValue=cell.innerText

if(cellValue!==""&&cellValue==+cellValue)
cellValue=+cellValue

ranges.forEach(function(range){

if(
R>=range.s.r &&
R<=range.e.r &&
outRow.length>=range.s.c &&
outRow.length<=range.e.c
){

for(var i=0;i<=range.e.c-range.s.c;++i)
outRow.push(null)

}

})

if(rowspan||colspan){

rowspan=Number(rowspan)||1
colspan=Number(colspan)||1

ranges.push({
s:{r:R,c:outRow.length},
e:{r:R+rowspan-1,c:outRow.length+colspan-1}
})

}

outRow.push(cellValue!==""?cellValue:null)

if(colspan)
for(var k=0;k<colspan-1;++k)
outRow.push(null)

}

out.push(outRow)

}

return[out,ranges]

}

function sheet_from_array_of_arrays(data){

var ws={}
var range={
s:{c:10000000,r:10000000},
e:{c:0,r:0}
}

for(var R=0;R!=data.length;++R){

for(var C=0;C!=data[R].length;++C){

if(range.s.r>R)range.s.r=R
if(range.s.c>C)range.s.c=C
if(range.e.r<R)range.e.r=R
if(range.e.c<C)range.e.c=C

var cell={v:data[R][C]}

if(cell.v==null)continue

var cell_ref=XLSX.utils.encode_cell({c:C,r:R})

if(typeof cell.v==="number")cell.t="n"
else if(typeof cell.v==="boolean")cell.t="b"
else cell.t="s"

ws[cell_ref]=cell

}

}

if(range.s.c<10000000)
ws["!ref"]=XLSX.utils.encode_range(range)

return ws

}

function Workbook(){

if(!(this instanceof Workbook))
return new Workbook()

this.SheetNames=[]
this.Sheets={}

}

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

}

</script>

</body>
</html>

👉点击进入 我的网站

相关推荐
xiaoye-duck7 小时前
《C++ 项目:手写大模型接入 SDK》Gemini接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
nice_lcj52010 小时前
Java Lambda 表达式入门:怎么写、怎么用、常用方法有哪些
java·开发语言·后端·面试
码农小河6610 小时前
基于SSM+JSP+MySQL的在线医疗服务系统的设计与实现
java·开发语言·mysql
系统集成-鹰翔11 小时前
ERP图片改名后仍命中识别缓存:缓存键、十分钟到期与调用计数
javascript·经验分享·后端
FlyWIHTSKY12 小时前
vue2和vue3有什么区别,用法上有哪些区别
前端·javascript·vue.js
程序员大阳14 小时前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例
Dream-Y.ocean14 小时前
鸿蒙PC平台逻控 PLC 编辑器适配实战:基于 Electron 壳方案的纯 JavaScript 梯形图编程与仿真引擎开发
javascript·编辑器·harmonyos
nice_lcj52015 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
百事牛科技15 小时前
Excel的三种密码:防看、防存、防乱改,各管各的
windows·excel
紧跟先前的步伐15 小时前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang