From 4f021b880c8b2327ace68641902c7663a2360ec9 Mon Sep 17 00:00:00 2001 From: AfzalAhmad Date: Sun, 15 Oct 2017 20:54:48 +0200 Subject: [PATCH] refactor: date util file and new data types for ExcelColumn --- README.md | 50 +++++++++++++++++++++- lib/components/ExcelFile.js | 82 ++++--------------------------------- lib/elements/ExcelColumn.js | 2 + lib/utils/DataUtil.js | 72 ++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 76 deletions(-) create mode 100644 lib/utils/DataUtil.js diff --git a/README.md b/README.md index f7078ec7..0d5bead8 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,52 @@ A data export library built with and for [React](http://facebook.github.io/react/index.html). -## New version 0.1.0-rc +## Example -I've just started implementing this library for data export in react. +```javascript +import React from "react" +import * from "react-data-export" + +class App extends React.Component { + const dataSet1 = [ + { + name: "Johson", + amount: 30000, + sex: 'M', + is_married: true + }, + { + name: "Monika", + amount: 355000, + sex: 'F', + is_married: false + }, + { + name: "John", + amount: 250000, + sex: 'M', + is_married: false + }, + { + name: "Josef", + amount: 450500, + sex: 'M', + is_married: true + } + ]; + + render() { + return ( + + + + + + col.is_married ? "Married" : "Single"} /> + + + ); + } +} +``` diff --git a/lib/components/ExcelFile.js b/lib/components/ExcelFile.js index 787c3ff6..50f02fc1 100644 --- a/lib/components/ExcelFile.js +++ b/lib/components/ExcelFile.js @@ -3,79 +3,8 @@ 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 */ +import { strToArrBuffer, excelSheetFromAoA } from "../utils/DataUtil"; class ExcelFile extends React.Component { static props = { @@ -90,6 +19,11 @@ class ExcelFile extends React.Component { } }; + static defaultProps = { + filename: "Download.xlsx", + element: + } + constructor(props) { super(props); @@ -123,11 +57,11 @@ class ExcelFile extends React.Component { }; React.Children.forEach(this.props.children, sheet => { - wb.Sheets[sheet.props.name] = sheetFromAOA(this.createSheetData(sheet)); + wb.Sheets[sheet.props.name] = excelSheetFromAoA(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); + saveAs(new Blob([strToArrBuffer(wbout)], { type: "application/octet-stream" }), this.props.filename); } render() { diff --git a/lib/elements/ExcelColumn.js b/lib/elements/ExcelColumn.js index 5572b6c7..050e8256 100644 --- a/lib/elements/ExcelColumn.js +++ b/lib/elements/ExcelColumn.js @@ -6,6 +6,8 @@ export default class ExcelColumn extends React.Component { static propsTypes = { label: PropTypes.string.isRequired, value: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.bool, PropTypes.string, PropTypes.func ]).isRequired diff --git a/lib/utils/DataUtil.js b/lib/utils/DataUtil.js new file mode 100644 index 00000000..ee767a45 --- /dev/null +++ b/lib/utils/DataUtil.js @@ -0,0 +1,72 @@ +import XLSX from "xlsx"; + +const strToArrBuffer = (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; +}; + +const dateToNumber = (v, date1904) => { + if (date1904) { + v += 1462; + } + + var epoch = Date.parse(v); + + return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); +}; + +const excelSheetFromAoA = (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 = dateToNumber(cell.v); + } else { + cell.t = 's'; + } + + ws[cellRef] = cell; + } + } + + if (range.s.c < 10000000) { + ws['!ref'] = XLSX.utils.encode_range(range); + } + + return ws; +}; + +export { strToArrBuffer, dateToNumber, excelSheetFromAoA };