引言
在Web开发中,导出Excel功能是常见需求。传统方案通常需要后端配合生成文件,但今天我们将介绍一种纯前端实现方案,通过HTML模板+Base64编码实现Excel导出,无需依赖后端服务。本文将详细解析代码实现原理,并提供可直接使用的解决方案。
方案特点
- 纯前端实现:无需后端参与,前端独立完成文件生成和下载
- 兼容主流浏览器:支持Chrome/Firefox/Safari/Edge等现代浏览器
- 支持复杂数据:可处理文本、多行文本、图片等多种数据类型
- 样式可控:通过HTML/CSS自定义表格样式和布局
核心代码解析
1. 浏览器兼容性处理
javascript复制代码
const getExplorer = () => { | |
const explorer = window.navigator.userAgent; | |
if (explorer.indexOf('MSIE') >= 0) return 'ie'; | |
if (explorer.indexOf('Firefox') >= 0) return 'Firefox'; | |
if (explorer.indexOf('Chrome') >= 0) return 'Chrome'; | |
if (explorer.indexOf('Opera') >= 0) return 'Opera'; | |
if (explorer.indexOf('Safari') >= 0) return 'Safari'; | |
}; |
通过检测userAgent
识别浏览器类型,对IE浏览器直接提示不支持。
2. Excel文件生成核心逻辑
javascript复制代码
const tableToNotIE = (function () { | |
const uri = 'data:application/vnd.ms-excel;base64,'; | |
const template = ` | |
<html xmlns:o="urn:schemas-microsoft-com:office:office" | |
xmlns:x="urn:schemas-microsoft-com:office:excel" | |
xmlns="http://www.w3.org/TR/REC-html40"> | |
<head> | |
<meta charset="UTF-8"> | |
<!--[if gte mso 9]> | |
<xml> | |
<x:ExcelWorkbook> | |
<x:ExcelWorksheets> | |
<x:ExcelWorksheet> | |
<x:Name>{worksheet}</x:Name> | |
<x:WorksheetOptions> | |
<x:DisplayGridlines/> | |
</x:WorksheetOptions> | |
</x:ExcelWorksheet> | |
</x:ExcelWorksheets> | |
</x:ExcelWorkbook> | |
</xml> | |
<![endif]--> | |
</head> | |
<body> | |
<table style="table-layout: fixed; width: 100%;">{table}</table> | |
</body> | |
</html> | |
`; | |
const base64 = (s) => { | |
const encoder = new TextEncoder(); | |
const data = encoder.encode(s); | |
return btoa(String.fromCharCode(...data)); | |
}; | |
return (table, name) => { | |
const ctx = { worksheet: name, table }; | |
const url = uri + base64(format(template, ctx)); | |
// Firefox特殊处理 | |
if (navigator.userAgent.indexOf('Firefox') > -1) { | |
window.location.href = url; | |
} else { | |
const aLink = document.createElement('a'); | |
aLink.href = url; | |
aLink.download = name || ''; | |
const event = new MouseEvent('click'); | |
aLink.dispatchEvent(event); | |
} | |
}; | |
})(); |
实现原理:
- 使用HTML表格结构作为Excel文件模板
- 通过Base64编码将HTML内容转换为Excel可识别的格式
- 利用
<a>
标签的download属性触发文件下载 - 对Firefox浏览器做特殊处理(直接跳转下载)
3. 数据转换处理
javascript复制代码
// 文本处理 | |
function getTextHtml(val) { | |
return `<td style="text-align: center">${val}</td>`; | |
} | |
// 多行文本处理 | |
function getTextHtmls(val) { | |
const textsHtml = val.map(item => `<div>${item}</div>`).join(''); | |
return `<td style="text-align: left">${textsHtml}</td>`; | |
} | |
// 图片处理 | |
function getImageHtmls(val) { | |
const imgsHtml = val.map(items => | |
`<div><img src="${items.url}" width="100" height="100" loading="lazy" /></div>` | |
).join(''); | |
return `<td style="text-align: center; vertical-align: top;">${imgsHtml}</td>`; | |
} |
支持的数据类型:
- 单行文本(text)
- 多行文本(texts)
- 图片数组(images)
- 可扩展其他数据类型(通过typeMap配置)
4. 导出入口函数
javascript复制代码
export const table2excelNew = (...options) => { | |
// 解析参数 | |
const { column, data, excelName, captionName } = resolveOptions(options); | |
// 生成表格结构 | |
let table = captionName ? `<caption>${captionName}</caption>` : ''; | |
table += column.reduce((html, col) => | |
html + `<th>${col.title}</th>`, '' | |
, `<thead><tr>`); | |
table += `</thead>`; | |
table += data.reduce((html, row) => | |
html + column.reduce((tr, col) => | |
tr + (typeMap[col.type || 'text'](row[col.key])), '' | |
, `<tr>` | |
) + `</tr>` | |
, `<tbody>`); | |
table += `</tbody>`; | |
// 执行导出 | |
exportToExcel(table, excelName); | |
}; |
使用示例
javascript复制代码
// 定义列配置 | |
const columns = [ | |
{ title: '姓名', key: 'name', type: 'text' }, | |
{ title: '年龄', key: 'age', type: 'text' }, | |
{ title: '照片', key: 'avatar', type: 'images' }, | |
{ title: '备注', key: 'remark', type: 'texts' } | |
]; | |
// 模拟数据 | |
const data = [ | |
{ | |
name: '张三', | |
age: 25, | |
avatar: [{ url: 'avatar1.jpg' }], | |
remark: ['优秀员工', '技术骨干'] | |
}, | |
{ | |
name: '李四', | |
age: 30, | |
avatar: [{ url: 'avatar2.jpg' }, { url: 'avatar3.jpg' }], | |
remark: ['团队领导'] | |
} | |
]; | |
// 执行导出 | |
table2excelNew( | |
columns, | |
data, | |
'员工信息表', | |
'员工数据导出' | |
); |
方案优势
- 零后端依赖:纯前端实现,适合快速开发
- 轻量高效:无需引入庞大库文件
- 样式可控:通过CSS自由定义表格样式
- 扩展性强:可轻松添加新数据类型处理
注意事项
- IE不支持:需提前做浏览器检测提示
- 复杂样式限制:不支持Excel高级样式(如合并单元格、公式等)
- 大文件性能:处理超大数据量时可能影响性能
- 安全限制:部分浏览器可能限制Blob下载
优化方向
- 使用Blob对象:替代Base64编码提升大文件性能
- 添加样式支持:通过CSS类名增强表格样式控制
- 支持复杂表头:实现多级表头合并功能
- 添加导出进度提示:提升用户体验
总结
本方案通过HTML模板+Base64编码实现了纯前端Excel导出功能,适用于大多数简单表格导出场景。开发者可根据实际需求扩展数据类型和样式处理逻辑。对于复杂需求,建议考虑使用专业库(如xlsx.js)或后端生成方案。完整代码已封装成可复用工具函数,可直接集成到项目中。