Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add files via upload
Added autoDownload prop. When the component is mounted, the file is downloaded without using a button (none rendered components)
  • Loading branch information
ciuliene authored Jan 7, 2021
commit ece0cc03679ccb6a67869280a58e02c342a69a61
120 changes: 120 additions & 0 deletions ReactHTMLTableToExcel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* 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,
autoDownload: PropTypes.bool,
};

const defaultProps = {
id: 'button-download-as-xls',
className: 'button-download',
buttonText: 'Download',
autoDownload: false,
};

class ReactHTMLTableToExcel extends Component {
constructor(props) {
super(props);
this.handleDownload = this.handleDownload.bind(this);
}

componentDidMount() {
if (this.props.autoDownload) this.handleDownload();
}

static base64(s) {
return window.btoa(unescape(encodeURIComponent(s)));
}

static format(s, c) {
return s.replace(/{(\w+)}/g, (m, p) => c[p]);
}

handleDownload() {
if (!document) {
if (process.env.NODE_ENV !== 'production') {
console.error('Failed to access document object');
}

return null;
}

if (document.getElementById(this.props.table).nodeType !== 1 || document.getElementById(this.props.table).nodeName !== 'TABLE') {
if (process.env.NODE_ENV !== 'production') {
console.error('Provided table property is not html table element');
}

return null;
}

const table = document.getElementById(this.props.table).outerHTML;
const sheet = String(this.props.sheet);
const filename = `${String(this.props.filename)}.xls`;

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: sheet || 'Worksheet',
table,
};

// 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>'}${table}</body></html>`,
];
const blobObject = new Blob(fileData);
document.getElementById('react-html-table-to-excel').click()(() => {
window.navigator.msSaveOrOpenBlob(blobObject, filename);
});

return true;
}

const element = window.document.createElement('a');
element.href =
uri +
ReactHTMLTableToExcel.base64(
ReactHTMLTableToExcel.format(template, context),
);
element.download = filename;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);

return true;
}

render() {
if (this.props.autoDownload) return null;
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;
12 changes: 10 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ var propTypes = {
sheet: _propTypes2.default.string.isRequired,
id: _propTypes2.default.string,
className: _propTypes2.default.string,
buttonText: _propTypes2.default.string
buttonText: _propTypes2.default.string,
autoDownload: _propTypes2.default.bool
};

var defaultProps = {
id: 'button-download-as-xls',
className: 'button-download',
buttonText: 'Download'
buttonText: 'Download',
autoDownload: false
};

var ReactHTMLTableToExcel = function (_Component) {
Expand All @@ -51,6 +53,11 @@ var ReactHTMLTableToExcel = function (_Component) {
}

_createClass(ReactHTMLTableToExcel, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.autoDownload) this.handleDownload();
}
}, {
key: 'handleDownload',
value: function handleDownload() {
if (!document) {
Expand Down Expand Up @@ -104,6 +111,7 @@ var ReactHTMLTableToExcel = function (_Component) {
}, {
key: 'render',
value: function render() {
if (this.props.autoDownload) return null;
return _react2.default.createElement(
'button',
{
Expand Down