1.利用XLSX插件和Blob对象
该方法最终还是转换成blob进行下载,适用于数据量较少,不需要和后端进行交互的情况。eg:导出模板、导出少量统计数据情况
import * as XLSX from "xlsx";
const util = {
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
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;
},
openDownloadDialog(url, saveName) {
if (typeof url == "object" && url instanceof Blob) {
url = URL.createObjectURL(url); // 创建blob地址
}
var aLink = document.createElement("a");
aLink.href = url;
aLink.download = saveName || ""; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
var event;
if (window.MouseEvent) event = new MouseEvent("click");
else {
event = document.createEvent("MouseEvents");
event.initMouseEvent(
"click",
true,
false,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
);
}
aLink.dispatchEvent(event);
},
}
export default util
调用以下方法进行下载
downLoadExcel = () => {
const aoa = [
["姓名", "年龄","年级],
["小明", "18","高二"],
["小张", "19","高三"],
];
var sheet = XLSX.utils.aoa_to_sheet(aoa);
util.openDownloadDialog(
util.sheet2blob(sheet),
"学生信息导入模板.xlsx"
);
};
2. react + antd table + react-html-table-to-excel 直接对表格导出
下载依赖
yarn add react-html-table-to-excel
import React,{ useState } from 'react';
import { Table } from 'antd';
import ReactHTMLTableToExcel from 'react-html-table-to-excel';
class exportExcelTable extend React.component {
constructor(props){
super(props)
this.state={
selectId:''
}
}
componentDidMount(){
const tableCon = ReactDOM.findDOMNode(this.refs['tables']); // 通过ref属性找到该table
const table = tableCon.querySelector('table'); //获取table
table.setAttribute('id', 'table-to-xls') //给该table设置属性
}
// 导出前可做相应判断
handleExportable = (e) => {
if (!this.state.selectId) {
e.stopPropagation()
console.log('请先选择需要导出的模板')
}
}
return (
<>
<div className={s.conditionWrap} onClick={handleExportable}>
<ReactHTMLTableToExcel
className="download-table-xls-button exportBtn"
filename={selectCard ? ccxiIndustryName + '行业打分卡' : '评级打分卡'}
sheet="sheet1"
buttonText="导出Excel"
id="test-table-xls-button"
table="table-to-xls"
/>
</div>
<Table
ref='tables'
dataSource={dataSource}
columns={columns}
bordered
pagination={false}
className='exportTableWrap'
/>
</>
)
}
export default exportExcelTable
3. 请求后端接口使用Blob进行导出
通过接口获取 src/actions
import axios from 'axios';
import util from '@src/util';
// 导出excel
export const exportExcel = (params, callback) => async (dispatch) => {
const result = await axios({
url: HOST_NAME_EXPORT_URL,// 接口地址....
method: 'POST',
data: JSON.stringify(params),
headers: {// 可携带token等
'Content-Type': 'application/json;charset=UTF-8',
},
responseType: 'blob',// 接收类型指定为blob
})
const response = await util.judgeErrorByResponseType(result) // 对返回内容进行校验,捕获错误
if (callback) callback(response)
};
src/util
const util = {
// 导出excel(response响应结果,fileName文件名)
exportExcel(response,fileName) {
const data = response.data
const blob = new Blob([data], {type: 'application/octet-stream'});
const url = URL.createObjectURL(blob);
const exportLink = document.createElement('a');
// 文件名可自行指定 或从响应头中获取
const exportName = fileName || decodeURIComponent(
response.headers['content-disposition'].split(';')[1].split('=')[1]
)
exportLink.setAttribute('download',exportName);
exportLink.href = url;
document.body.appendChild(exportLink);
exportLink.click();
},
// 捕捉导出错误
judgeErrorByResponseType(response) {
return new Promise((resolve, reject) => {
if (response.headers['content-type'] && response.headers['content-type'].includes('json')) {
// 此处拿到的data才是blob
const { data } = response
const reader = new FileReader()
reader.onload = () => {
const { result } = reader
const errorInfos = JSON.parse(result)
const { msg } = errorInfos
reject(new Error(msg))
message.error(msg,1.5)
}
reader.onerror = err => {
reject(err)
}
reader.readAsText(data)
} else {
resolve(response)
}
})
},
}
export default util
导出
import util from '@src/util';
const ExportPage = (props) => {
const exportData = () => {
this.props.exportExcel(searchParams, (res) => {
util.exportExcel(res)
})
}
return (
<div onClick={exportData} className='exportBtn'>导出</div>
)
}