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
Updated dependencies to use react 16. Added children to the button so…
… we can render icons and other content if desired. The tests do not work yet, there are enzyme issues to deal with.
  • Loading branch information
Sean Walker committed Jun 29, 2022
commit b519be86cad8109450c5c368d7e8eb781cacca81
132 changes: 66 additions & 66 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
{
"name": "react-html-table-to-excel",
"version": "2.0.0",
"description": "Small react component for converting and downloading HTML table to Excel file",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/babel ./src/ReactHTMLTableToExcel.jsx -o index.js",
"prepublish": "npm run build",
"client:test": "NODE_ENV=test jest",
"client:test:watch": "NODE_ENV=test jest --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zsusac/ReactHTMLTableToExcel.git"
},
"keywords": [
"react",
"excel",
"table",
"html",
"xls"
],
"author": "Zvonimir Susac <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/zsusac/ReactHTMLTableToExcel/issues"
},
"homepage": "https://github.com/zsusac/ReactHTMLTableToExcel#readme",
"jest": {
"rootDir": "./",
"moduleNameMapper": {
"^.+\\.(css|less)$": "<rootDir>/CSSStub.js"
},
"collectCoverage": true,
"coverageDirectory": "<rootDir>/../../coverage",
"verbose": true,
"coveragePathIgnorePatterns": [
"<rootDir>/../../node_modules/"
]
},
"peerDependencies": {
"react": "^15.x.x"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chai": "^3.5.0",
"chai-enzyme": "^0.6.1",
"enzyme": "^2.8.2",
"eslint": "^3.19.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^5.0.1",
"eslint-plugin-react": "^7.0.0",
"jest": "^20.0.1",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-test-renderer": "^15.5.4",
"sinon": "^2.2.0"
},
"dependencies": {
"prop-types": "^15.5.10"
}
}
"name": "react-html-table-to-excel",
"version": "3.0.0",
"description": "Small react component for converting and downloading HTML table to Excel file",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/babel ./src/ReactHTMLTableToExcel.jsx -o index.js",
"prepublish": "npm run build",
"client:test": "NODE_ENV=test jest",
"client:test:watch": "NODE_ENV=test jest --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zsusac/ReactHTMLTableToExcel.git"
},
"keywords": [
"react",
"excel",
"table",
"html",
"xls"
],
"author": "Zvonimir Susac <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/zsusac/ReactHTMLTableToExcel/issues"
},
"homepage": "https://github.com/zsusac/ReactHTMLTableToExcel#readme",
"jest": {
"rootDir": "./",
"moduleNameMapper": {
"^.+\\.(css|less)$": "<rootDir>/CSSStub.js"
},
"collectCoverage": true,
"coverageDirectory": "<rootDir>/../../coverage",
"verbose": true,
"coveragePathIgnorePatterns": [
"<rootDir>/../../node_modules/"
]
},
"peerDependencies": {
"react": "^16.x.x"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chai": "^3.5.0",
"chai-enzyme": "^1.0.0-beta.1",
"enzyme": "^3.11.0",
"eslint": "^8.18.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^6.6.0",
"eslint-plugin-react": "^7.30.1",
"jest": "^20.0.4",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-test-renderer": "^16.14.0",
"sinon": "^2.2.0"
},
"dependencies": {
"prop-types": "^15.8.1"
}
}
173 changes: 87 additions & 86 deletions src/ReactHTMLTableToExcel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,108 +3,109 @@ 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,
table: PropTypes.string.isRequired,
filename: PropTypes.string.isRequired,
sheet: PropTypes.string.isRequired,
id: PropTypes.string,
className: PropTypes.string,
buttonText: PropTypes.string,
children: PropTypes.element
};

const defaultProps = {
id: 'button-download-as-xls',
className: 'button-download',
buttonText: 'Download',
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]);
}

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 =
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]);
}

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 =
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),
ReactHTMLTableToExcel.format(template, context)
);
element.download = filename;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);

return true;
}

render() {
return (
<button
id={this.props.id}
className={this.props.className}
type="button"
onClick={this.handleDownload}
>
{this.props.buttonText}
</button>
);
}
element.download = filename;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);

return true;
}

render() {
return (
<button
id={this.props.id}
className={this.props.className}
type="button"
onClick={this.handleDownload}
>
{this.props.children ? this.props.children : this.props.buttonText}
</button>
);
}
}

ReactHTMLTableToExcel.propTypes = propTypes;
Expand Down