React CSV import widget with user-customizable mapping
npm install freeman-react-csv-importersh
using NPM
npm install --save react-csv-importer
using Yarn
yarn add react-csv-importer
`
This package is easy to fork with your own customizations, and you can use your fork directly as a Git dependency in any of your projects, see below.
Example Usage
`js
import { Importer, ImporterField } from 'react-csv-importer';
// include the widget CSS file whichever way your bundler supports it
import 'react-csv-importer/dist/index.css';
// in your component code:
assumeNoHeaders={false} // optional, keeps "data has headers" checkbox off by default
restartable={false} // optional, lets user choose to upload another file when import is complete
onStart={({ file, preview, fields, columnFields }) => {
// optional, invoked when user has mapped columns and started import
prepMyAppForIncomingData();
}}
processChunk={async (rows, { startIndex }) => {
// required, may be called several times
// receives a list of parsed objects based on defined fields and user column mapping;
// (if this callback returns a promise, the widget will wait for it before parsing more data)
for (row of rows) {
await myAppMethod(row);
}
}}
onComplete={({ file, preview, fields, columnFields }) => {
// optional, invoked right after import is done (but user did not dismiss/reset the widget yet)
showMyAppToastNotification();
}}
onClose={({ file, preview, fields, columnFields }) => {
// optional, if this is specified the user will see a "Finish" button after import is done,
// which will call this when clicked
goToMyAppNextPage();
}}
// CSV options passed directly to PapaParse if specified:
// delimiter={...}
// newline={...}
// quoteChar={...}
// escapeChar={...}
// comments={...}
// skipEmptyLines={...}
// delimitersToGuess={...}
// chunkSize={...} // defaults to 10000
// encoding={...} // defaults to utf-8, see FileReader API
>
;
`
In the above example, if the user uploads a CSV file with column headers "Name", "Email" and so on, the columns will be automatically matched to fields with same labels. If any of the headers do not match, the user will have an opportunity to manually remap columns to the defined fields.
The preview object available to some callbacks above contains a snippet of CSV file information (only the first portion of the file is read, not the entire thing). The structure is:
`js
{
rawData: '...', // raw string contents of first file chunk
columns: [ // array of preview columns, e.g.:
{ index: 0, header: 'Date', values: [ '2020-09-20', '2020-09-25' ] },
{ index: 1, header: 'Name', values: [ 'Alice', 'Bob' ] }
],
skipHeaders: false, // true when user selected that data has no headers
parseWarning: undefined, // any non-blocking warning object produced by Papa Parse
}
`
Importer component children may be defined as a render-prop function that receives an object with preview and file fields (see above). It can then, for example, dynamically return different fields depending which headers are present in the CSV.
Dependencies
- Papa Parse for CSV parsing
- react-dropzone for file upload
- react-use-gesture for drag-and-drop
Internationalization (i18n) and Localization (l10n)
You can swap the text used in the UI to a different locale.
`
import { Importer, deDE } from 'react-csv-importer';
// provide the locale to main UI
locale={deDE}
// normal props, etc
/>
`
You can also pass your own fully custom locale definition as the locale value. See ImporterLocale interface in src/locale for the full definition, and use an existing locale like enUS as basis. For better performance, please ensure that the value is stable (i.e. does not change on every render).
Local Development
Perform local git clone, etc. Then ensure modules are installed:
`sh
yarn
`
To start Storybook to have a hot-reloaded local sandbox:
`sh
yarn storybook
`
To run the end-to-end test suite:
`sh
yarn test
`
You can use your own fork of this library in your own project by referencing the forked repo as a Git dependency. NPM will then run the prepare` script, which runs the same Webpack/dist command as when the NPM package is published, so your custom dependency should work just as conveniently as the stock NPM version. Of course if your custom fixes could be useful to the rest of us then please submit a PR to this repo!