SPFx export to CSV – using React CSV and Office UI Fabric control

I used React CSV to implement export to CSV functionality in my webpart which worked well in local and site workbench, but when deployed into a site I got a weird blob redirection 404 not found error message.

https:///blob:/1a49b01c-ddb2-4c31-af1c-8ea3676be5d8 (404 not found)

Broke my head for 2days, luckily came through this brilliant demo by Aakash in community call

Solution/work around:

You will get this error when react-csv is used like this in webpart

<CSVLink data={csvData}>Download me</CSVLink>;

Instead use it with combination of Office UI react control, it worked fantastic in all browsers (IE, Chrome and Edge)

<CSVLink data={this.state.userRequests} filename={'Requests.csv'}>
                  <CommandBarButton  iconProps={{ iconName: 'ExcelLogoInverse' }} text='Export to Excel' />
 </CSVLink>

Finally, I was able to create a webpart with export to “CSV/Excel” option.

Step 1: Create a standard SPFx React webpart

Step 2: Install the dependency packages

Once the react webpart is created open the project in VS code and install these

Install React-csv for export to csv feature

npm i react-csv
npm install @types/react-csv

Install Office UI fabric control to add the Export to Excel icon button

npm install @pnp/spfx-controls-react --save --save-exact

Step 3: Add Import statements

Open the webpart “.tsx” file and add the below impart statements

import { CommandBarButton } from 'office-ui-fabric-react/lib/Button';
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from 'office-ui-fabric-react/lib/DetailsList';
import { CSVLink } from "react-csv";
import { SPHttpClient } from '@microsoft/sp-http';

Step 4: Add code logic to retrieve list items and Export to CSV control

In the “.tsx” file under default class add the below methods to retrieve SharePoint list using RESTAPI.

export default class Exportcsv extends React.Component<IExportcsvProps, IExportcsvState> {
  private userRequests: IUserRequest[] = [];
  constructor(props: IExportcsvProps) {
    super(props);    
    this.state = {
      userRequests: this.userRequests
    };
  }
  public componentDidMount() {
    const restApi = `${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/GetByTitle('Requests')/items?$select=Title,Requestor,RequestDate,Location,Status`;
    this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1)
      .then(resp => { return resp.json(); })
      .then(items => {
        this.setState({userRequests: items.value});
      });
  }

  public render(): React.ReactElement<IExportcsvProps> {
    const columns: IColumn[] = [
      {
        key: 'column1',
        name: 'Title',
        fieldName: 'Title',
        minWidth: 100,
        maxWidth: 400,
        isResizable: true
      },
      {
        key: 'column2',
        name: 'Requestor',
        fieldName: 'Requestor',
        minWidth: 100,
        maxWidth: 400,
        isResizable: true
      },
      {
        key: 'column3',
        name: 'Location',
        fieldName: 'Location',
        minWidth: 100,
        maxWidth: 400,
        isResizable: true
      },
      {
        key: 'column4',
        name: 'RequestDate',
        fieldName: 'RequestDate',
        minWidth: 100,
        maxWidth: 400,
        isResizable: true
      },
      {
        key: 'column5',
        name: 'Status',
        fieldName: 'Status',
        minWidth: 100,
        maxWidth: 400,
        isResizable: true
      },
    ];
    return (
      <div className={ styles.exportcsv }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <CSVLink data={this.state.userRequests} filename={'Requests.csv'}>
                  <CommandBarButton  iconProps={{ iconName: 'ExcelLogoInverse' }} text='Export to Excel' />
              </CSVLink>
            </div>
          </div><br/>
          <DetailsList
              items={this.state.userRequests}
              columns={columns}
              isHeaderVisible={true}
              setKey='set'
              layoutMode={DetailsListLayoutMode.justified}
              selectionMode={SelectionMode.none}
            />
        </div>
      </div>
    );
  }
}
Gulp build
Gulp bundle –ship
Gulp package-solution --ship

Find the full project code here GitHub.

Thanks for reading my blog. Sharingiscaring.