一、背景
遇到到动态表单+导出的场景, 后端不愿意为动态表单写导出, 于是只能前端做了
二、实现
1. 如何纯前端导出文件
实现原理还是通过a标签去下载和导出。
一般情况下,a标签的href属性,仅支持同源的绝对路径、相对路径和锚链接,当a标签具有download属性后,则href可以支持Data URL 和Blob URL,并提供下载
2. 如何导出excel
在创建Data URL 和Blob URL,我们可以设置其的数据类型和编码
Data URL
data URI scheme(数据URI方案)是URI(统一资源标识符)方案。目的是将一些小的数据。直接嵌入到网页中,从而不用再从外部文件加载。
data:[<media type>],<data>
- data 表示方案名称
- <media type> 表示媒体类型, 可以有多个参数, 通过分号分隔, 比如我们可以用来指定字符集 charset;数据的的mime类型;以及数据编码格式等
data:[<mime type>][;charset=<charset>][;<encoding>], <encoded data>
- [<mime type>] 可选项, 数据类型(如image/png、text/plain等)
- [;charset=<charset>] 可选项,源文本的字符集编码方式(如utf-8)
- [;<encoding>], 数据编码方式(US-ASCII,BASE64两种), 默认US-ASCII
- <encoded data> 即编码后的数据, 如果不是[;<encoding>]方式编码后的数据,会报异常
- <data> 即上面的<encoded data>
示例:
data:,文本数据
data:image/png;base64,base64编码的png图片数据
data:text/csv;charset=utf-8,表格文本数据
下载
interface DataSourceNode {
[propsString: string]: string | number;
}
interface Column extends DataSourceNode {
title: string; // 中文名
dataIndex: string; // 英文名
}
/**
* 导出excel
* @param dataSource 数据源
* @param columns 表格列配置
* @param name 导出文件名
*/
export function exportToExcel(dataSource: DataSourceNode[], columns: Column[], name = '出.csv'){
// 表头
let str = `${columns.map((item) => item.title).join(',')}\n`;
//增加\t为了不让表格显示科学计数法或者其他格式
for (let i = 0; i < dataSource.length; i++) {
for (let j = 0; j < columns.length; j++) {
const key = dataSource[j].dataIndex;
str += `${dataSource[i][key] + '\t'},`;
}
str += '\n';
}
// 添加data:前缀、数据类型、字符集编码方式
// \ufeff 用于给数据添加BOM头,避免excel解析出错
// encodeURIComponent处理中文和上面的特殊字符
const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
//通过创建a标签实现
const link = document.createElement('a');
link.href = uri;
//对下载的文件命名
link.download = name;
link.click();
}
Blob URL
一些较老的chrome可能不支持Data URL, 这时我们也可以使用Blob来解决
Blob 对象表示一个不可变、原始数据的类文件对象
我们可以通过创建一个Blob对象,并获取其地址即 Blob URL,再将其地址赋值给href,用于下载
...
// 创建blob对象
const blob = new Blob([`\ufeff${str}`], {type: 'text/csv,charset=UTF-8'}
// 获取blob url
const uri = URL.createObjectURL(blob);
link.href = uri;
...
三、总结
本文主要介绍了通过Data URL、Blob URL和a标签的download属性纯前端下载excel文件,其它文件也可以通过这种方式来下载。
文中若有错漏或者可深入、优化之处, 望请不吝赐教