securedeveloper / react-data-export

Export dataset in react.
https://securedeveloper.github.io/react-data-export/
MIT License
179 stars 191 forks source link

Date type column is not working #139

Open absriv02 opened 4 years ago

absriv02 commented 4 years ago

I have date column in xlsx when download. but when i applied filter its not working as expected, i need to change that date column from string to date type. and when i did that i got error below

xlsx.js?3478:4334 Uncaught TypeError: s.t.match is not a function at write_sst_xml (xlsx.js?3478:4334) at write_sst (xlsx.js?3478:8914) at write_zip (xlsx.js?3478:11783) at write_zip_type (xlsx.js?3478:11859) at Object.writeSync [as write] (xlsx.js?3478:11873) at ExcelFile.download (ExcelFile.js?4d75:104) at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:149) at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:199) at invokeGuardedCallback (react-dom.development.js?61bb:256) at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?61bb:270)

My reason:

Steps to reproduce: use date type for date column (ex : new Date())

Lib Version: ^0.6.0

absriv02 commented 4 years ago

please help on this.

w35l3y commented 3 years ago

Sadly, I had to use data instead of dataSet to make it work. Also, the cell value should be referenced directly instead of using {value: new Date(), style: {...}}

anjanikumarjangid commented 3 years ago

Sadly, I had to use data instead of dataSet to make it work. Also, the cell value should be referenced directly instead of using {value: new Date(), style: {...}}

can you please explain, how to do it? I am facinng the same issue

w35l3y commented 3 years ago

Sadly, I had to use data instead of dataSet to make it work. Also, the cell value should be referenced directly instead of using {value: new Date(), style: {...}}

can you please explain, how to do it? I am facinng the same issue

Use new Date().toJSON() or any other format you want. This library doesn't work well with type Date.

w35l3y commented 3 years ago
import React from 'react'
import ReactExport from 'react-data-export'
import { moment } from 'utils'
import PropTypes from 'prop-types'

const ExcelFile = ReactExport.ExcelFile
const { ExcelSheet, ExcelColumn } = ReactExport.ExcelFile

const transformData = v => {
  // Date is formatted here! If you don't use `moment`, you may use `v instanceof Date` and format accordingly
  if (moment.isMoment(v)) return v.toDate()
  if (v === false || v === 0) return v
  return v || null
}

const mapCell2object = headers => row =>
  headers.reduce(
    (acc, { value }) => ({
      ...acc,
      [value]: transformData(row[value])
    }),
    {}
  )

const mapCell2array = headers => row => headers.map(({ value }) => transformData(row[value]))

const mapDataSet = headers => rows => [
  {
    columns: headers.map(({ label }) => label),
    data: []
      .concat(rows)
      .filter(row => row)
      .map(mapCell2array(headers))
  }
]

const renderSheet = ({ headers = [], data, dataSet, ...otherProps }, key) => {
  let value = [].concat(dataSet || data).filter(row => row)

  if (dataSet) {
    return <ExcelSheet key={key} {...otherProps} dataSet={mapDataSet(headers)(value)} />
  }

  return (
    <ExcelSheet key={key} {...otherProps} data={value.map(mapCell2object(headers))}>
      {headers.map((header, i) => <ExcelColumn key={i} {...header} />)}
    </ExcelSheet>
  )
}

const LocalRelatorioXLS = ({
  element,
  children,
  value = children,
  loaded = !!value,
  ...otherProps
}) => {
  if (!loaded) return null

  return (
    <ExcelFile {...{ element, filename: 'Download' }} {...otherProps}>
      {value.map(renderSheet)}
    </ExcelFile>
  )
}

LocalRelatorioXLS.propTypes = {
  element: PropTypes.any,
  children: PropTypes.arrayOf(PropTypes.object),
  value: PropTypes.arrayOf(PropTypes.object),
  loaded: PropTypes.bool
}

export default LocalRelatorioXLS
<LocalRelatorioXLS>
{[{
  name: 'sheetname',
  headers: [{label: 'Field 1', value: 'field1'}, {label: 'Field 2', value: 'field2'}],
  data: [{field1: 'value', field2: 'value'}]
}]}
</LocalRelatorioXLS>
anjanikumarjangid commented 3 years ago

import React, { Component } from 'react'; import ReactExport from 'react-data-export';

const ExcelFile = ReactExport.ExcelFile; var ExcelSheet = ReactExport.ExcelFile.ExcelSheet;

function dateValidator(dataValue){ if(new Date(dataValue) instanceof Date && !isNaN(new Date(dataValue).valueOf())){ // Duration of a day in MilliSeconds const oneDay=1000 60 60 * 24; // Excel starts reading dates from 1900-1-1 and date parameter is our date which we are providing in string format as "2023-4-23" //excel reads dates as five digit numbers as difference in date given and 1900-1-1 //adding 2 beacuse when we get difference it doesn't include those specific days const differenceOfDays = Math.round(Math.abs((new Date("1900-1-1") -new Date(dataValue))/oneDay))+2; return differenceOfDays; } else{ return dataValue; } }

const multiDataSet = [ { columns: [ {title: "Headings", width: {wpx: 80}},//pixels width {title: "Dates", width: {wch: 40}},//char width {title: "Colors", width: {wpx: 90}}, ], data: [ [ {value: "H2", style: {font: {sz: "18", bold: true}}}, {value: dateValidator("2031-5-16"),style:{numFmt:'m/d/yyyy',fill: {patternType: "solid", fgColor: {rgb: "FF00FF00"}}}}, {value: "Blue", style: {fill: {patternType: "solid", fgColor: {rgb: "FFFFC0CB"}}}}, ], [ {value: "H2", style: {font: {sz: "18", bold: true}}}, {value: dateValidator("2031-6-18"),style:{numFmt:'m/d/yyyy'}}, {value: "Blue", style: {fill: {patternType: "solid", fgColor: {rgb: "FFFFC0CB"}}}}, ], ] } ];

export default class ExcelExport extends Component { render() { return ( //use same div after return as it is used in example ) } }