mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-07-01 14:40:02 +00:00
implement export csv
This commit is contained in:
86
packages/react-bootstrap-table2-example/examples/csv/index.js
vendored
Normal file
86
packages/react-bootstrap-table2-example/examples/csv/index.js
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitContext, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitContext, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { SearchBar, searchFactory } = Search;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitContext.Provider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
>
|
||||
<ToolkitContext.Consumer>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
search={ searchFactory({
|
||||
...props.searchProps
|
||||
}) }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitContext.Consumer>
|
||||
</ToolkitContext.Provider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitContext.Provider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
exportCSV
|
||||
>
|
||||
<ToolkitContext.Consumer>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<CSVExport { ...props.csvProps } />
|
||||
<hr />
|
||||
<BootstrapTable { ...props.baseProps } />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitContext.Consumer>
|
||||
</ToolkitContext.Provider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -133,6 +133,9 @@ import FullyCustomSearch from 'examples/search/fully-custom-search';
|
||||
import SearchFormattedData from 'examples/search/search-formatted';
|
||||
import CustomSearchValue from 'examples/search/custom-search-value';
|
||||
|
||||
// CSV
|
||||
import ExportCSV from 'examples/csv';
|
||||
|
||||
// loading overlay
|
||||
import EmptyTableOverlay from 'examples/loading-overlay/empty-table-overlay';
|
||||
import TableOverlay from 'examples/loading-overlay/table-overlay';
|
||||
@@ -289,6 +292,9 @@ storiesOf('Table Search', module)
|
||||
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
||||
.add('Custom Search Value', () => <CustomSearchValue />);
|
||||
|
||||
storiesOf('Export CSV', module)
|
||||
.add('Basic Export CSV', () => <ExportCSV />);
|
||||
|
||||
storiesOf('EmptyTableOverlay', module)
|
||||
.add('Empty Table Overlay', () => <EmptyTableOverlay />)
|
||||
.add('Table Overlay', () => <TableOverlay />);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import statelessDrcorator from './statelessOp';
|
||||
|
||||
import createContext from './src/search/context';
|
||||
|
||||
const ToolkitContext = React.createContext();
|
||||
|
||||
class ToolkitProvider extends React.Component {
|
||||
class ToolkitProvider extends statelessDrcorator(React.Component) {
|
||||
static propTypes = {
|
||||
keyField: PropTypes.string.isRequired,
|
||||
data: PropTypes.array.isRequired,
|
||||
@@ -17,11 +18,21 @@ class ToolkitProvider extends React.Component {
|
||||
PropTypes.shape({
|
||||
searchFormatted: PropTypes.bool
|
||||
})
|
||||
]),
|
||||
exportCSV: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.shape({
|
||||
fileName: PropTypes.string,
|
||||
separator: PropTypes.string,
|
||||
ignoreHeader: PropTypes.bool,
|
||||
noAutoBOM: PropTypes.bool
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
search: null
|
||||
search: false,
|
||||
exportCSV: false
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@@ -53,6 +64,9 @@ class ToolkitProvider extends React.Component {
|
||||
searchProps: {
|
||||
onSearch: this.onSearch
|
||||
},
|
||||
csvProps: {
|
||||
onExport: this.handleExportCSV
|
||||
},
|
||||
baseProps
|
||||
} }
|
||||
>
|
||||
|
||||
@@ -4,3 +4,4 @@ import ToolkitProvider from './provider';
|
||||
export default ToolkitProvider;
|
||||
export const ToolkitContext = Context;
|
||||
export { default as Search } from './src/search';
|
||||
export { default as CSVExport } from './src/csv';
|
||||
|
||||
@@ -43,5 +43,8 @@
|
||||
"prop-types": "^15.0.0",
|
||||
"react": "^16.3.0",
|
||||
"react-dom": "^16.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"file-saver": "1.3.8"
|
||||
}
|
||||
}
|
||||
|
||||
33
packages/react-bootstrap-table2-toolkit/src/csv/button.js
vendored
Normal file
33
packages/react-bootstrap-table2-toolkit/src/csv/button.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ExportCSVButton = (props) => {
|
||||
const {
|
||||
onExport,
|
||||
children,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={ onExport }
|
||||
{ ...rest }
|
||||
>
|
||||
{ children }
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
ExportCSVButton.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onExport: PropTypes.func.isRequired,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object
|
||||
};
|
||||
ExportCSVButton.defaultProps = {
|
||||
className: 'react-bs-table-csv-btn btn btn-default',
|
||||
style: {}
|
||||
};
|
||||
|
||||
export default ExportCSVButton;
|
||||
64
packages/react-bootstrap-table2-toolkit/src/csv/exporter.js
vendored
Normal file
64
packages/react-bootstrap-table2-toolkit/src/csv/exporter.js
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/* eslint no-unneeded-ternary: 0 */
|
||||
import FileSaver from 'file-saver';
|
||||
|
||||
export const getMetaInfo = columns =>
|
||||
columns
|
||||
.map(column => ({
|
||||
field: column.dataField,
|
||||
type: column.csvType || String,
|
||||
formatter: column.csvFormatter,
|
||||
formatExtraData: column.formatExtraData,
|
||||
header: column.csvText || column.text,
|
||||
export: column.csvExport === false ? false : true,
|
||||
row: Number(column.row) || 0,
|
||||
rowSpan: Number(column.rowSpan) || 1,
|
||||
colSpan: Number(column.colSpan) || 1
|
||||
}))
|
||||
.filter(_ => _.export);
|
||||
|
||||
export const transform = (
|
||||
data,
|
||||
meta,
|
||||
{
|
||||
separator,
|
||||
ignoreHeader
|
||||
}
|
||||
) => {
|
||||
const visibleColumns = meta.filter(m => m.export);
|
||||
let content = '';
|
||||
// extract csv header
|
||||
if (!ignoreHeader) {
|
||||
content += visibleColumns.map(m => `"${m.header}"`).join(separator);
|
||||
content += '\n';
|
||||
}
|
||||
// extract csv body
|
||||
if (data.length === 0) return content;
|
||||
content += data
|
||||
.map((row, rowIndex) =>
|
||||
visibleColumns.map((m) => {
|
||||
let cellContent = row[m.field];
|
||||
if (m.formatter) {
|
||||
cellContent = m.formatter(cellContent, row, rowIndex, m.formatExtraData);
|
||||
}
|
||||
if (m.type === String) {
|
||||
return `"${cellContent}"`;
|
||||
}
|
||||
return cellContent;
|
||||
}).join(separator)).join('\n');
|
||||
|
||||
return content;
|
||||
};
|
||||
|
||||
export const save = (
|
||||
content,
|
||||
{
|
||||
noAutoBOM,
|
||||
fileName
|
||||
}
|
||||
) => {
|
||||
FileSaver.saveAs(
|
||||
new Blob(['\ufeff', content], { type: 'text/plain;charset=utf-8' }),
|
||||
fileName,
|
||||
noAutoBOM
|
||||
);
|
||||
};
|
||||
3
packages/react-bootstrap-table2-toolkit/src/csv/index.js
vendored
Normal file
3
packages/react-bootstrap-table2-toolkit/src/csv/index.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import ExportCSVButton from './button';
|
||||
|
||||
export default { ExportCSVButton };
|
||||
24
packages/react-bootstrap-table2-toolkit/src/op/csv.js
vendored
Normal file
24
packages/react-bootstrap-table2-toolkit/src/op/csv.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { getMetaInfo, transform, save } from '../csv/exporter';
|
||||
|
||||
const csvDefaultOptions = {
|
||||
fileName: 'spreadsheet.csv',
|
||||
separator: ',',
|
||||
ignoreHeader: false,
|
||||
noAutoBOM: true
|
||||
};
|
||||
|
||||
export default Base =>
|
||||
class CSVOperation extends Base {
|
||||
handleExportCSV = () => {
|
||||
const { columns, data, exportCSV } = this.props;
|
||||
const meta = getMetaInfo(columns);
|
||||
const options = exportCSV === true ?
|
||||
csvDefaultOptions :
|
||||
{
|
||||
...csvDefaultOptions,
|
||||
...exportCSV
|
||||
};
|
||||
const content = transform(data, meta, options);
|
||||
save(content, options);
|
||||
}
|
||||
};
|
||||
5
packages/react-bootstrap-table2-toolkit/src/op/index.js
vendored
Normal file
5
packages/react-bootstrap-table2-toolkit/src/op/index.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import csvOperation from './csv';
|
||||
|
||||
export default {
|
||||
csvOperation
|
||||
};
|
||||
4
packages/react-bootstrap-table2-toolkit/statelessOp.js
vendored
Normal file
4
packages/react-bootstrap-table2-toolkit/statelessOp.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import Operation from './src/op';
|
||||
|
||||
export default Base =>
|
||||
class StatelessOperation extends Operation.csvOperation(Base) {};
|
||||
7
packages/react-bootstrap-table2-toolkit/yarn.lock
Normal file
7
packages/react-bootstrap-table2-toolkit/yarn.lock
Normal file
@@ -0,0 +1,7 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
file-saver@1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8"
|
||||
Reference in New Issue
Block a user