3

Hi I hope the title is enough to understand my problem. There is no error when exporting data, I just want that if the checkbox is unchecked or false it will hide the excel column of excel when exported. And if the checkbox is checked or true it will display or show the excel column when the excel is exported.

const [filteredData, setfilteredData] = useState(false)
const [checked, setChecked] = React.useState(false);
const handleDisplay = (event) => {
    console.log(event.target.checked)
    setChecked(event.target.checked);
}
....,

<Checkbox checked={checked} onChange={handleDisplay}  /> Display Name<br></br>

 <ExcelExported exportClass={'admin-add-btn'} filteredData={filteredData} checked={checked}></ExcelExported>

ExcelExported.js

import React from 'react'
import ReactExport from 'react-export-excel'
import { Button } from '@material-ui/core'



const ExcelFile = ReactExport.ExcelFile
const ExcelSheet = ReactExport.ExcelFile.ExcelSheet;
const ExcelColumn = ReactExport.ExcelFile.ExcelColumn;

function ExcelExported(props) {

    const { exportClass, filteredData, checked } = props
    console.log(checked)
    const fileNameFormatted = 'Student Information'
    return (
        <div>
            <ExcelFile filename="Student Information" element={
                <Button style={{ textTransform: 'none', minWidth: '240px' }}
                    className={exportClass}
                    variant='contained'
                // onClick={handlePrint}
                >
                    Export
                </Button>
            }>
                <ExcelSheet data={filteredData} name="Users" >
                    <ExcelColumn label="Student Name" value="name"  hide={checked}/>
                </ExcelSheet>
            </ExcelFile>

        </div >
    )
}

export default ExcelExported

this is my https://www.npmjs.com/package/react-export-excel library for exporting excel sheet

what i've tried so far is putting hide={checked} there is no error but even the checkbox is unchecked, it display the column, and i also tried this

{checked ? (<ExcelColumn label="Student Name" value="name")/>:(null)}

and i received this error

enter image description here

2
  • One thing to note is that on this line : {checked ? (<ExcelColumn label="Student Name" value="name"):(null)} it seems like you are not closing the <ExcelColumn tag anywhere ( you are missing the /> after value="name" ) . Also if that isn't the issue, maybe you could edit an existing sandbox like codesandbox.io/s/wrdew to give a minimal reproducible example :) Commented Sep 16, 2022 at 14:08
  • Sorry, its typo Commented Sep 17, 2022 at 3:04

2 Answers 2

3
+100

It's because you pass in null as a child component of ExcelFile.

Let's locate the (approximate) line the stacktrace is showing in react-export-excel's source. It loops over all children of that component and will always try to access the props property of them.

// src/ExcelPlugin/components/ExcelFile.js

const columns = sheet.props.children;
const sheetData = [
  React.Children.map(columns, column => column.props.label)
];

So this component will only ever work (i.e. not crash) if all of its children are objects with this expected structure.

You'll get the same error with checked && <ExcelColumn/>, where it receives false as a child. In a regular React component both null and false are "ignored" (they don't have output). But because this component loops over it with React.children, it just gets the exact list you put into it.

Further down the code it looks like it also has no way to prevent a column from being included. You can try passing in other things, but it's likely still going to be included as an extra comma separate column.

Perhaps this could be facilitated by this library by ignoring these values too. It could get tricky, though. As the amount of columns always needs to match the data. So it's understandable that this component does not provide this level of flexibility at the moment.

Alternative

Instead of using <ExcelColumn/> components, you can define the columns in the dataSet object. An example from their documentation:

const multiDataSet = [
  {
    columns: [
      { value: "Name", widthPx: 50 }, // width in pixels
      { value: "Salary", widthCh: 20 }, // width in charachters
    ],
    data: [
      // ...
    ],
  },
  // ...
];

// ...
<ExcelSheet dataSet={multiDataSet} name="Organization"/>

This way you have direct control over the columns list and can filter it depending on certain hook values.

You'll also have to guarantee the rows have the same filters applied.

Here's a quick example implementation showing how to manage the state of the hidden rows. This could be done completely different depending on your use case / existing state management solution.

const allColumns = [{value: "columnA"}, {value: "columnB"} /* ... */];
const [hiddenColumns, setHiddenColumns] = useState({});
const isVisible = col => !hiddenColumns[col.name];
const toggleColumn = col => setHiddenColumns({
  ...hiddenColumns,
  [col.name]: !hiddenColumns[col.name],
})

// Get indexes of hidden columns to hide them in data too.
const hiddenIndexes = Object.entries(hiddenColumns).filter(([,hidden]) => hidden).map(
  ([hiddenCol]) => allColumns.findIndex(column => column.value === hiddenCol)
)
const dataSet = {
  // ...
  columns: allColumns.filter(isVisible);
  data: rows.map(
    cells => cells.filter(
      (cell, index) => !hiddenIndexes.includes(index)
    )
  ),
}

return <Fragment>
  <ExcelFile><ExcelSheet {...{dataSet}}/></ExcelFile>
  {allColumns.map(
    col => 
      <Checkbox
        checked={!isVisible(col)}
        onChange={()=> toggleColumn(col.name)}
      >
        col.value
      </Checkbox>
  )}
</Fragment>
Sign up to request clarification or add additional context in comments.

Comments

0

Hope this will work

{checked && <ExcelColumn label="Student Name" value="name"/>}

4 Comments

I've already done that, and I received error just like in my post
I think error occurs because <ExcelSheet/> has not a single <ExcelColumn/> as a child.
If you had more than one column issue did not occur in the first place. One thing you can try is applying condition on <ExcelSheet/> instead of <ExcelColumn/>
This will have the same problem, explained here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.