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文件下载的主要内容,如果未能解决你的问题,请参考以下文章

table数据转为excel文件下载

python读取excel数据转为json格式

SQLite 数据提取转为excel

前端接收到数据转为Excel,借助第三方包,清洗数据——转为业务数据类型

用手机如何将Excel格式转为PDF文件

如何将Excel文件转为json格式的呢