From 94530e3829ea492d1972184b3c9c360c560a6737 Mon Sep 17 00:00:00 2001 From: AfzalAhmad Date: Sun, 15 Oct 2017 12:54:33 +0200 Subject: [PATCH] feat: add excel data export ^--^ ^------------^ | | | +-> package file-saver | +-> package xlsx | +-> new components (ExcelColumn, ExcelSheet and ExcelFile) | +-------------------> --- .babelrc | 3 +- .eslintrc | 466 ++++++++++++++++++++++-------------- lib/components/ExcelFile.js | 138 +++++++++++ lib/elements/ExcelColumn.js | 17 ++ lib/elements/ExcelSheet.js | 25 ++ lib/index.js | 8 +- package-lock.json | 133 +++++++++- package.json | 5 + 8 files changed, 613 insertions(+), 182 deletions(-) create mode 100644 lib/components/ExcelFile.js create mode 100644 lib/elements/ExcelColumn.js create mode 100644 lib/elements/ExcelSheet.js diff --git a/.babelrc b/.babelrc index d4e5f8d4..c672f6df 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,4 @@ { - "presets": ["es2015", "react"] + "presets": ["es2015", "react"], + "plugins": ["transform-class-properties"] } diff --git a/.eslintrc b/.eslintrc index 192b9f9f..86799298 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,181 +1,293 @@ { - "root": true, - "parser": "babel-eslint", - "plugins": [/*"import", */"jsx-a11y", "react"], - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "jest": true, - "node": true - }, - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true, - "generators": true, - "experimentalObjectRestSpread": true - } - }, - "settings": { - "import/ignore": [ - "node_modules", - "\\.(json|css|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$" - ], - "import/extensions": [".js"], - "import/resolver": { - "node": { - "extensions": [".js", ".json"] - } - } - }, - "rules": { - // http://eslint.org/docs/rules/ - "array-callback-return": "warn", - "camelcase": "warn", - "curly": "warn", - "default-case": ["warn", { "commentPattern": "^no default$" }], - "dot-location": ["warn", "property"], - "eol-last": "warn", - "eqeqeq": ["warn", "always"], - "indent": ["warn", 4, { "SwitchCase": 1 }], - "guard-for-in": "warn", - "keyword-spacing": "warn", - "new-parens": "warn", - "no-array-constructor": "warn", - "no-caller": "warn", - "no-cond-assign": ["warn", "always"], - "no-const-assign": "warn", - "no-control-regex": "warn", - "no-delete-var": "warn", - "no-dupe-args": "warn", - "no-dupe-class-members": "warn", - "no-dupe-keys": "warn", - "no-duplicate-case": "warn", - "no-empty-character-class": "warn", - "no-empty-pattern": "warn", - "no-eval": "warn", - "no-ex-assign": "warn", - "no-extend-native": "warn", - "no-extra-bind": "warn", - "no-extra-label": "warn", - "no-fallthrough": "warn", - "no-func-assign": "warn", - "no-global-assign": "warn", - "no-implied-eval": "warn", - "no-invalid-regexp": "warn", - "no-iterator": "warn", - "no-label-var": "warn", - "no-labels": ["warn", { "allowLoop": false, "allowSwitch": false }], - "no-lone-blocks": "warn", - "no-loop-func": "warn", - "no-mixed-operators": ["warn", { - "groups": [ - ["&", "|", "^", "~", "<<", ">>", ">>>"], - ["==", "!=", "===", "!==", ">", ">=", "<", "<="], - ["&&", "||"], - ["in", "instanceof"] + "extends": "eslint:recommended", + "root": true, + "parser": "babel-eslint", + "plugins": [ /*"import", */ + "jsx-a11y", + "react" + ], + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "jest": true, + "node": true + }, + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true, + "generators": true, + "experimentalObjectRestSpread": true + } + }, + "settings": { + "import/ignore": [ + "node_modules", + "\\.(json|css|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$" + ], + "import/extensions": [ + ".js" + ], + "import/resolver": { + "node": { + "extensions": [ + ".js", + ".json" + ] + } + } + }, + "rules": { + // http://eslint.org/docs/rules/ + "array-callback-return": "warn", + "camelcase": "warn", + "curly": "warn", + "default-case": [ + "warn", + { + "commentPattern": "^no default$" + } + ], + "dot-location": [ + "warn", + "property" + ], + "eol-last": "warn", + "eqeqeq": [ + "warn", + "always" + ], + "indent": [ + "warn", + 4, + { + "SwitchCase": 1 + } + ], + "guard-for-in": "warn", + "keyword-spacing": "warn", + "new-parens": "warn", + "no-array-constructor": "warn", + "no-caller": "warn", + "no-cond-assign": [ + "warn", + "always" + ], + "no-const-assign": "warn", + "no-control-regex": "warn", + "no-delete-var": "warn", + "no-dupe-args": "warn", + "no-dupe-class-members": "warn", + "no-dupe-keys": "warn", + "no-duplicate-case": "warn", + "no-empty-character-class": "warn", + "no-empty-pattern": "warn", + "no-eval": "warn", + "no-ex-assign": "warn", + "no-extend-native": "warn", + "no-extra-bind": "warn", + "no-extra-label": "warn", + "no-fallthrough": "warn", + "no-func-assign": "warn", + "no-global-assign": "warn", + "no-implied-eval": "warn", + "no-invalid-regexp": "warn", + "no-iterator": "warn", + "no-label-var": "warn", + "no-labels": [ + "warn", + { + "allowLoop": false, + "allowSwitch": false + } + ], + "no-lone-blocks": "warn", + "no-loop-func": "warn", + "no-mixed-operators": [ + "warn", + { + "groups": [ + [ + "&", + "|", + "^", + "~", + "<<", + ">>", + ">>>" + ], + [ + "==", + "!=", + "===", + "!==", + ">", + ">=", + "<", + "<=" ], - "allowSamePrecedence": false - }], - "no-multi-str": "warn", - "no-new-func": "warn", - "no-new-object": "warn", - "no-new-symbol": "warn", - "no-new-wrappers": "warn", - "no-obj-calls": "warn", - "no-octal": "warn", - "no-octal-escape": "warn", - "no-redeclare": "warn", - "no-regex-spaces": "warn", - "no-restricted-syntax": [ - "warn", - "LabeledStatement", - "WithStatement" + [ + "&&", + "||" + ], + [ + "in", + "instanceof" + ] ], - "no-script-url": "warn", - "no-self-assign": "warn", - "no-self-compare": "warn", - "no-sequences": "warn", - "no-shadow-restricted-names": "warn", - "no-sparse-arrays": "warn", - "no-template-curly-in-string": "warn", - "no-this-before-super": "warn", - "no-throw-literal": "warn", - "no-undef": "warn", - "no-unexpected-multiline": "warn", - "no-unreachable": "warn", - "no-unsafe-negation": "warn", - "no-unused-expressions": "warn", - "no-unused-labels": "warn", - "no-unused-vars": ["warn", { "vars": "local", "args": "none" }], - "no-use-before-define": ["warn", "nofunc"], - "no-useless-computed-key": "warn", - "no-useless-concat": "warn", - "no-useless-constructor": "warn", - "no-useless-escape": "warn", - "no-useless-rename": ["warn", { - "ignoreDestructuring": false, - "ignoreImport": false, - "ignoreExport": false - }], - "no-with": "warn", - "no-whitespace-before-property": "warn", - "object-curly-spacing": ["warn", "always"], - "operator-assignment": ["warn", "always"], - "radix": "warn", - "require-yield": "warn", - "rest-spread-spacing": ["warn", "never"], - "semi": "warn", - "strict": ["warn", "never"], - "unicode-bom": ["warn", "never"], - "use-isnan": "warn", - "valid-typeof": "warn", - "react/jsx-boolean-value": "warn", - "react/jsx-closing-bracket-location": "warn", - "react/jsx-curly-spacing": "warn", - "react/jsx-equals-spacing": ["warn", "never"], - "react/jsx-first-prop-new-line": ["warn", "multiline"], - "react/jsx-handler-names": "warn", - "react/jsx-indent": ["warn", 2], - "react/jsx-indent-props": ["warn", 2], - "react/jsx-key": "warn", - "react/jsx-max-props-per-line": "warn", - "react/jsx-no-bind": ["warn", {"allowArrowFunctions": true}], - "react/jsx-no-comment-textnodes": "warn", - "react/jsx-no-duplicate-props": ["warn", { "ignoreCase": true }], - "react/jsx-no-undef": "warn", - "react/jsx-pascal-case": ["warn", { - "allowAllCaps": true, - "ignore": [] - }], - "react/jsx-sort-props": "warn", - "react/jsx-tag-spacing": "warn", - "react/jsx-uses-react": "warn", - "react/jsx-uses-vars": "warn", - "react/jsx-wrap-multilines": "warn", - "react/no-deprecated": "warn", - "react/no-did-mount-set-state": "warn", - "react/no-did-update-set-state": "warn", - "react/no-direct-mutation-state": "warn", - "react/no-is-mounted": "warn", - "react/no-unused-prop-types": "warn", - "react/prefer-es6-class": "warn", - "react/prefer-stateless-function": "warn", - "react/prop-types": "warn", - "react/react-in-jsx-scope": "warn", - "react/require-render-return": "warn", - "react/self-closing-comp": "warn", - "react/sort-comp": "warn", - "react/sort-prop-types": "warn", - "react/style-prop-object": "warn", - "react/void-dom-elements-no-children": "warn" - //https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules - // "jsx-a11y/aria-role": "warn", - // "jsx-a11y/img-has-alt": "warn", - // "jsx-a11y/img-redundant-alt": "warn", - // "jsx-a11y/no-access-key": "warn" + "allowSamePrecedence": false } - } - \ No newline at end of file + ], + "no-multi-str": "warn", + "no-new-func": "warn", + "no-new-object": "warn", + "no-new-symbol": "warn", + "no-new-wrappers": "warn", + "no-obj-calls": "warn", + "no-octal": "warn", + "no-octal-escape": "warn", + "no-redeclare": "warn", + "no-regex-spaces": "warn", + "no-restricted-syntax": [ + "warn", + "LabeledStatement", + "WithStatement" + ], + "no-script-url": "warn", + "no-self-assign": "warn", + "no-self-compare": "warn", + "no-sequences": "warn", + "no-shadow-restricted-names": "warn", + "no-sparse-arrays": "warn", + "no-template-curly-in-string": "warn", + "no-this-before-super": "warn", + "no-throw-literal": "warn", + "no-undef": "warn", + "no-unexpected-multiline": "warn", + "no-unreachable": "warn", + "no-unsafe-negation": "warn", + "no-unused-expressions": "warn", + "no-unused-labels": "warn", + "no-unused-vars": [ + "warn", + { + "vars": "local", + "args": "none" + } + ], + "no-use-before-define": [ + "warn", + "nofunc" + ], + "no-useless-computed-key": "warn", + "no-useless-concat": "warn", + "no-useless-constructor": "warn", + "no-useless-escape": "warn", + "no-useless-rename": [ + "warn", + { + "ignoreDestructuring": false, + "ignoreImport": false, + "ignoreExport": false + } + ], + "no-with": "warn", + "no-whitespace-before-property": "warn", + "object-curly-spacing": [ + "warn", + "always" + ], + "operator-assignment": [ + "warn", + "always" + ], + "radix": "warn", + "require-yield": "warn", + "rest-spread-spacing": [ + "warn", + "never" + ], + "semi": "warn", + "strict": [ + "warn", + "never" + ], + "unicode-bom": [ + "warn", + "never" + ], + "use-isnan": "warn", + "valid-typeof": "warn", + "react/jsx-boolean-value": "warn", + "react/jsx-closing-bracket-location": "warn", + "react/jsx-curly-spacing": "warn", + "react/jsx-equals-spacing": [ + "warn", + "never" + ], + "react/jsx-first-prop-new-line": [ + "warn", + "multiline" + ], + "react/jsx-handler-names": "warn", + "react/jsx-indent": [ + "warn", + 2 + ], + "react/jsx-indent-props": [ + "warn", + 2 + ], + "react/jsx-key": "warn", + "react/jsx-max-props-per-line": "warn", + "react/jsx-no-bind": [ + "warn", + { + "allowArrowFunctions": true + } + ], + "react/jsx-no-comment-textnodes": "warn", + "react/jsx-no-duplicate-props": [ + "warn", + { + "ignoreCase": true + } + ], + "react/jsx-no-undef": "warn", + "react/jsx-pascal-case": [ + "warn", + { + "allowAllCaps": true, + "ignore": [] + } + ], + "react/jsx-sort-props": "warn", + "react/jsx-tag-spacing": "warn", + "react/jsx-uses-react": "warn", + "react/jsx-uses-vars": "warn", + "react/jsx-wrap-multilines": "warn", + "react/no-deprecated": "warn", + "react/no-did-mount-set-state": "warn", + "react/no-did-update-set-state": "warn", + "react/no-direct-mutation-state": "warn", + "react/no-is-mounted": "warn", + "react/no-unused-prop-types": "warn", + "react/prefer-es6-class": "warn", + "react/prefer-stateless-function": "warn", + "react/prop-types": "warn", + "react/react-in-jsx-scope": "warn", + "react/require-render-return": "warn", + "react/self-closing-comp": "warn", + "react/sort-comp": "warn", + "react/sort-prop-types": "warn", + "react/style-prop-object": "warn", + "react/void-dom-elements-no-children": "warn" + //https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules + // "jsx-a11y/aria-role": "warn", + // "jsx-a11y/img-has-alt": "warn", + // "jsx-a11y/img-redundant-alt": "warn", + // "jsx-a11y/no-access-key": "warn" + } +} \ No newline at end of file diff --git a/lib/components/ExcelFile.js b/lib/components/ExcelFile.js new file mode 100644 index 00000000..787c3ff6 --- /dev/null +++ b/lib/components/ExcelFile.js @@ -0,0 +1,138 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { saveAs } from "file-saver"; +import XLSX from "xlsx"; + +import ExcelColumn from "../elements/ExcelColumn"; +import ExcelSheet from "../elements/ExcelSheet"; + +/* tslint:disable */ +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; +} + +function datenum(v, date1904) { + if (date1904) { + v += 1462; + } + + var epoch = Date.parse(v); + + return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); +} + +function sheetFromAOA(data) { + var ws = {}; + var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } }; + + for (var R = 0; R != data.length; ++R) { + for (var C = 0; C != data[R].length; ++C) { + if (range.s.r > R) { + range.s.r = R; + } + + if (range.s.c > C) { + range.s.c = C; + } + + if (range.e.r < R) { + range.e.r = R; + } + + if (range.e.c < C) { + range.e.c = C; + } + + var cell = { v: data[R][C] }; + if (cell.v === null) { continue; } + + var cellRef = XLSX.utils.encode_cell({ c: C, r: R }); + if (typeof cell.v === 'number') { + cell.t = 'n'; + } else if (typeof cell.v === 'boolean') { + cell.t = 'b'; + } else if (cell.v instanceof Date) { + cell.t = 'n'; cell.z = XLSX.SSF._table[14]; + cell.v = datenum(cell.v); + } else { + cell.t = 's'; + } + + ws[cellRef] = cell; + } + } + + if (range.s.c < 10000000) { + ws['!ref'] = XLSX.utils.encode_range(range); + } + + return ws; +} +/* tslint:enable */ + +class ExcelFile extends React.Component { + static props = { + filename: PropTypes.string, + element: PropTypes.any, + children: function (props, propName, componentName) { + React.Children.forEach(props[propName], child => { + if (child.type !== ExcelSheet) { + throw new Error(' can only have as children. '); + } + }); + } + }; + + constructor(props) { + super(props); + + this.handleDownload = this.download.bind(this); + this.createSheetData = this.createSheetData.bind(this); + } + + createSheetData(sheet) { + const columns = sheet.props.children; + const sheetData = [React.Children.map(columns, column => column.props.label)]; + const data = typeof (sheet.props.data) === 'function' ? sheet.props.data() : sheet.props.data; + + data.forEach(row => { + const sheetRow = []; + + React.Children.forEach(columns, column => { + const getValue = typeof (column.props.value) === 'function' ? column.props.value : row => row[column.props.value]; + sheetRow.push(getValue(row) || ''); + }); + + sheetData.push(sheetRow); + }); + + return sheetData; + } + + download() { + const wb = { + SheetNames: React.Children.map(this.props.children, sheet => sheet.props.name), + Sheets: {} + }; + + React.Children.forEach(this.props.children, sheet => { + wb.Sheets[sheet.props.name] = sheetFromAOA(this.createSheetData(sheet)); + }); + + const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' }); + saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), this.props.filename); + } + + render() { + return ({this.props.element}); + } +} + +export default ExcelFile; diff --git a/lib/elements/ExcelColumn.js b/lib/elements/ExcelColumn.js new file mode 100644 index 00000000..5572b6c7 --- /dev/null +++ b/lib/elements/ExcelColumn.js @@ -0,0 +1,17 @@ +import React from "react"; +import PropTypes from "prop-types"; + + +export default class ExcelColumn extends React.Component { + static propsTypes = { + label: PropTypes.string.isRequired, + value: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.func + ]).isRequired + }; + + render() { + return null; + } +} diff --git a/lib/elements/ExcelSheet.js b/lib/elements/ExcelSheet.js new file mode 100644 index 00000000..5bf43898 --- /dev/null +++ b/lib/elements/ExcelSheet.js @@ -0,0 +1,25 @@ +import React from "react"; +import PropTypes from "prop-types"; +import ExcelColumn from "./ExcelColumn"; + + +export default class ExcelSheet extends React.Component { + static propsTypes = { + name: PropTypes.string.isRequired, + value: PropTypes.oneOfType([ + PropTypes.array, + PropTypes.func + ]).isRequired, + children: PropTypes.arrayOf((propValue, key) => { + const type = propValue[key]; + + if (type !== ExcelColumn) { + throw new Error(" can only have as children"); + } + }).isRequired + }; + + render() { + return null; + } +} diff --git a/lib/index.js b/lib/index.js index 944fccdc..c2c222d4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,9 @@ -const XlSX = XlSX || {}; +import ExcelFile from "./components/ExcelFile"; +import ExcelSheet from "./elements/ExcelSheet"; +import ExcelColumn from "./elements/ExcelColumn"; module.exports = { - XlSX + ExcelFile, + ExcelSheet, + ExcelColumn }; diff --git a/package-lock.json b/package-lock.json index 33097468..94576b57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,15 @@ } } }, + "adler-32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.1.0.tgz", + "integrity": "sha1-A1UaXH8O371PyPoSpoFJeOq2UcM=", + "requires": { + "exit-on-epipe": "1.0.1", + "printj": "1.1.0" + } + }, "ajv": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", @@ -650,6 +659,12 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, "babel-plugin-syntax-flow": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", @@ -662,6 +677,43 @@ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", "dev": true }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + }, + "dependencies": { + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + } + } + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -1234,6 +1286,15 @@ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, + "cfb": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-0.13.1.tgz", + "integrity": "sha512-XG+CMeWTJo1clHKxxtMjXq8ttBdpueXr5MLakYkyCf+sc8Va4PD0bt2YhGsGwVr0vS8sHDDbLC8TXIF5dD2kEA==", + "requires": { + "commander": "2.11.0", + "printj": "1.1.0" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1290,6 +1351,16 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "codepage": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.11.0.tgz", + "integrity": "sha1-EHYJW58DtcoE9Dhz+hpid0IoXeI=", + "requires": { + "commander": "2.11.0", + "exit-on-epipe": "1.0.1", + "voc": "1.0.0" + } + }, "color-convert": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", @@ -1308,8 +1379,7 @@ "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" }, "concat-map": { "version": "0.0.1", @@ -1352,6 +1422,15 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "crc-32": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.1.1.tgz", + "integrity": "sha1-XXOdXkxuNSrYME1zIj1IP+Va240=", + "requires": { + "exit-on-epipe": "1.0.1", + "printj": "1.1.0" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -1817,6 +1896,11 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -1909,6 +1993,11 @@ "object-assign": "4.1.1" } }, + "file-saver": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", + "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI=" + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -1971,6 +2060,14 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, + "frac": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.0.tgz", + "integrity": "sha1-3EN+nGpka2CxJ9gqxJAkZERcweM=", + "requires": { + "voc": "1.0.0" + } + }, "fs-readdir-recursive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", @@ -2860,6 +2957,11 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "printj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.0.tgz", + "integrity": "sha512-NbiNBOQ0GioHyeD3ni8wZB7ZmfU7mxIrqhWR5XSreX3rUVvk5UOwpzxOnWqrLdCtoBbdQ40sEwC+nXxxjlUo0A==" + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -3291,6 +3393,14 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "ssf": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.1.tgz", + "integrity": "sha1-8j2CtjeS71YIkInBzQyEjpEc26Y=", + "requires": { + "frac": "1.1.0" + } + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -3496,6 +3606,11 @@ "spdx-expression-parse": "1.0.4" } }, + "voc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/voc/-/voc-1.0.0.tgz", + "integrity": "sha512-mQwxWlK+zosxxDTqiFb9ZQBNgd794scgkhVwca7h9sEhvA52f3VzbOK+TOWeS8eSrFXnfuKrxElSPc5oLAetfw==" + }, "whatwg-fetch": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", @@ -3532,6 +3647,20 @@ "mkdirp": "0.5.1" } }, + "xlsx": { + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.11.5.tgz", + "integrity": "sha1-jGbNlxQL4HLj3TINErqgmWic63Q=", + "requires": { + "adler-32": "1.1.0", + "cfb": "0.13.1", + "codepage": "1.11.0", + "commander": "2.11.0", + "crc-32": "1.1.1", + "exit-on-epipe": "1.0.1", + "ssf": "0.10.1" + } + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index 27e69761..6b9ff37c 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "babel-cli": "^6.26.0", "babel-core": "^6.26.0", "babel-eslint": "^8.0.1", + "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "eslint": "^4.8.0", @@ -40,5 +41,9 @@ "lint": "eslint lib/**; exit 0", "lint:watch": "esw -w lib/**", "prepublish": "npm run build" + }, + "dependencies": { + "file-saver": "^1.3.3", + "xlsx": "^0.11.5" } }