table数据转为excel文件下载
Posted 秋天1014童话
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了table数据转为excel文件下载相关的知识,希望对你有一定的参考价值。
功能说明
本文讲解如何将table数据转为excel文件下载。亲测,当table有合并行/列时,下载的excel也会对应合并。
核心思想:
获取到table元素,根据其html组装为下载excel的文件地址,再下载
核心代码:
handleDownload()
// 获取table元素
const tableElem = ReactHTMLTableToExcel.getTableElem(this.props.table);
console.log('tableElem', tableElem)
if(!tableElem) return;
// 获取excel下载的url和文件名称
const filename = `$String(this.props.filename).xls`;
const tableHtml = tableElem.outerHTML;
const url = ReactHTMLTableToExcel.getExcelUri(tableHtml, this.props.sheet);
// 下载excel文件
ReactHTMLTableToExcel.downloadExcel(tableHtml, filename, url);
获取table元素
其中,getTableElem函数中的tableElemId参数 可以为 table元素的id ,也可以是 其父元素或其祖父元素的id,便于兼容不方便给table增加id属性时的情况。
static getTableElem(tableElemId) // table元素的id 或者 其祖父元素的id
if (!document || !tableElemId)
return null;
let tableElem = document.getElementById(tableElemId);
if(tableElem)
if(tableElem.nodeType !== 1 || tableElem.nodeName !== 'TABLE') // 不是元素类型,或者不是table
tableElem = tableElem.getElementsByTagName('table')[0] || null; //尝试寻找内部table元素
if(!tableElem)
tableElem = document.getElementsByTagName('table')[0];
if(!tableElem)
console.log('未找到table元素!')
return null;
return tableElem;
生成excel文件地址:
static base64(s)
return window.btoa(unescape(encodeURIComponent(s)));
static format(s, c)
return s.replace(/(\\w+)/g, (m, p) => c[p]);
static getExcelUri(table, sheetname)
const uri = 'data:application/vnd.ms-excel;base64,';
const template =
'<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-mic' +
'rosoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta cha' +
'rset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:Exce' +
'lWorksheet><x:Name>worksheet</x:Name><x:WorksheetOptions><x:DisplayGridlines/>' +
'</x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></' +
'xml><![endif]--></head><body>table</body></html>';
const context =
worksheet: String(sheetname) || 'Worksheet',
table,
;
const url = uri +
ReactHTMLTableToExcel.base64(
ReactHTMLTableToExcel.format(template, context),
);
return url;
下载excel文件
static downloadExcel(tableHtml, filename, url)
// If IE11
if (window.navigator.msSaveOrOpenBlob)
const fileData = [
`$'<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-mic' + 'rosoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta cha' + 'rset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:Exce' + 'lWorksheet><x:Name>worksheet</x:Name><x:WorksheetOptions><x:DisplayGridlines/>' + '</x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></' + 'xml><![endif]--></head><body>'$tableHtml</body></html>`,
];
const blobObject = new Blob(fileData);
document.getElementById('react-html-table-to-excel').click()(() =>
window.navigator.msSaveOrOpenBlob(blobObject, filename);
);
return true;
// 下载excel文件
const element = window.document.createElement('a');
element.href = url;
element.download = filename;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
附赠完整代码:
/* global window, document, Blob */
import React, Component from 'react';
import PropTypes from 'prop-types';
const propTypes =
table: PropTypes.string.isRequired,
filename: PropTypes.string.isRequired,
sheet: PropTypes.string.isRequired,
id: PropTypes.string,
className: PropTypes.string,
buttonText: PropTypes.string,
;
const defaultProps =
id: 'button-download-as-xls',
className: 'button-download',
buttonText: 'Download',
;
class ReactHTMLTableToExcel extends Component
constructor(props)
super(props);
this.handleDownload = this.handleDownload.bind(this);
static base64(s)
return window.btoa(unescape(encodeURIComponent(s)));
static format(s, c)
return s.replace(/(\\w+)/g, (m, p) => c[p]);
static getTableElem(tableElemId) // table元素的id 或者 其祖父元素的id
if (!document || !tableElemId)
return null;
let tableElem = document.getElementById(tableElemId);
if(tableElem)
if(tableElem.nodeType !== 1 || tableElem.nodeName !== 'TABLE') // 不是元素类型,或者不是table
tableElem = tableElem.getElementsByTagName('table')[0] || null; //尝试寻找内部table元素
if(!tableElem)
tableElem = document.getElementsByTagName('table')[0];
if(!tableElem)
console.log('未找到table元素!')
return null;
return tableElem;
static getExcelUri(table, sheetname)
const uri = 'data:application/vnd.ms-excel;base64,';
const template =
'<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-mic' +
'rosoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta cha' +
'rset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:Exce' +
'lWorksheet><x:Name>worksheet</x:Name><x:WorksheetOptions><x:DisplayGridlines/>' +
'</x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></' +
'xml><![endif]--></head><body>table</body></html>';
const context =
worksheet: String(sheetname) || 'Worksheet',
table,
;
const url = uri +
ReactHTMLTableToExcel.base64(
ReactHTMLTableToExcel.format(template, context),
);
return url;
static downloadExcel(tableHtml, filename, url)
// If IE11
if (window.navigator.msSaveOrOpenBlob)
const fileData = [
`$'<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-mic' + 'rosoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta cha' + 'rset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:Exce' + 'lWorksheet><x:Name>worksheet</x:Name><x:WorksheetOptions><x:DisplayGridlines/>' + '</x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></' + 'xml><![endif]--></head><body>'$tableHtml</body></html>`,
];
const blobObject = new Blob(fileData);
document.getElementById('react-html-table-to-excel').click()(() =>
window.navigator.msSaveOrOpenBlob(blobObject, filename);
);
return true;
// 下载excel文件
const element = window.document.createElement('a');
element.href = url;
element.download = filename;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
handleDownload()
// 获取table元素
const tableElem = ReactHTMLTableToExcel.getTableElem(this.props.table);
console.log('tableElem', tableElem)
if(!tableElem) return;
// 获取excel下载的url和文件名称
const filename = `$String(this.props.filename).xls`;
const tableHtml = tableElem.outerHTML;
const url = ReactHTMLTableToExcel.getExcelUri(tableHtml, this.props.sheet);
// 下载excel文件
ReactHTMLTableToExcel.downloadExcel(tableHtml, filename, url);
render()
return (
<button
id=this.props.id
className=this.props.className
type="button"
onClick=this.handleDownload
>
this.props.buttonText
</button>
);
ReactHTMLTableToExcel.propTypes = propTypes;
ReactHTMLTableToExcel.defaultProps = defaultProps;
export default ReactHTMLTableToExcel;
使用:
兼容不方便给table增加id属性时的情况:
<div id="table-to-xls">
<ReactHTMLTableToExcel
id="test-table-xls-button"
className="download-table-xls-button"
table="table-to-xls"
filename="tablexls"
sheet="tablexls"
buttonText="Download as XLS"/>
<Mytable>//封装好的table,table上没有透传id</Mytable>
</div>
直接在table上增加id的情况:
<div>
<ReactHTMLTableToExcel
id="test-table-xls-button"
className="download-table-xls-button"
table="table-to-xls"
filename="tablexls"
sheet="tablexls"
buttonText="Download as XLS"/>
<table id="table-to-xls">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
</div>
参考代码
ReactHTMLTableToExcel:https://www.npmjs.com/package/react-html-table-to-excel
本文在这个基础上,进行了代码抽离和获取table元素功能增强(兼容不方便给table增加id属性时的情况)。目的不是重复造轮子,是能够满足尽量多的业务场景。
以上是关于table数据转为excel文件下载的主要内容,如果未能解决你的问题,请参考以下文章