diff --git a/packages/react-bootstrap-table2-example/examples/csv/export-footer.js b/packages/react-bootstrap-table2-example/examples/csv/export-footer.js new file mode 100644 index 0000000..aab08ae --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/csv/export-footer.js @@ -0,0 +1,92 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const { ExportCSVButton } = CSVExport; +const products = productsGenerator(); + +const columns = [{ + dataField: 'id', + text: 'Product ID', + footer: 'Footer 1' +}, { + dataField: 'name', + text: 'Product Name', + footer: '', + footerFormatter: column => column.text +}, { + dataField: 'price', + text: 'Product Price', + footer: columnData => columnData.reduce((acc, item) => acc + item, 0) +}]; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit'; + +const { ExportCSVButton } = CSVExport; +const columns = [{ + dataField: 'id', + text: 'Product ID', + footer: 'Footer 1' +}, { + dataField: 'name', + text: 'Product Name', + footer: 'Footer 2' +}, { + dataField: 'price', + text: 'Product Price', + footer: 'Footer 3' +}]; + + + { + props => ( +
+ Export CSV!! +
+ +
+ ) + } +
+`; + +export default () => ( +
+ + { + props => ( +
+ Export CSV!! +
+ +
+ ) + } +
+ { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index 059e85c..829a358 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -213,6 +213,7 @@ import CSVColumnType from 'examples/csv/csv-column-type'; import CustomCSVButton from 'examples/csv/custom-csv-button'; import ExportCustomData from 'examples/csv/export-custom-data'; import CustomCSV from 'examples/csv/custom-csv'; +import ExportTableFooter from 'examples/csv/export-footer'; // Column toggle import BasicColumnToggle from 'examples/column-toggle'; @@ -484,7 +485,8 @@ storiesOf('Export CSV', module) .add('CSV Column Type', () => ) .add('Custom CSV Button', () => ) .add('Export Custom Data', () => ) - .add('Custom CSV', () => ); + .add('Custom CSV', () => ) + .add('Export Table Footer', () => ); storiesOf('EmptyTableOverlay', module) .addDecorator(bootstrapStyle()) diff --git a/packages/react-bootstrap-table2-toolkit/README.md b/packages/react-bootstrap-table2-toolkit/README.md index c28a623..84b2444 100644 --- a/packages/react-bootstrap-table2-toolkit/README.md +++ b/packages/react-bootstrap-table2-toolkit/README.md @@ -209,6 +209,9 @@ Custom the csv file separator. #### ignoreHeader - [bool] Default is `false`. Give true to avoid to attach the csv header. +#### ignoreFooter - [bool] +Default is `true`. Give `false` to attach the table footer if enabled. + #### noAutoBOM - [bool] Default is `true`. diff --git a/packages/react-bootstrap-table2-toolkit/context.js b/packages/react-bootstrap-table2-toolkit/context.js index 2a585e6..ef736e8 100644 --- a/packages/react-bootstrap-table2-toolkit/context.js +++ b/packages/react-bootstrap-table2-toolkit/context.js @@ -28,6 +28,7 @@ class ToolkitProvider extends statelessDecorator(React.Component) { fileName: PropTypes.string, separator: PropTypes.string, ignoreHeader: PropTypes.bool, + ignoreFooter: PropTypes.bool, noAutoBOM: PropTypes.bool, blobType: PropTypes.string, exportAll: PropTypes.bool, diff --git a/packages/react-bootstrap-table2-toolkit/src/csv/exporter.js b/packages/react-bootstrap-table2-toolkit/src/csv/exporter.js index 193933c..5c426b8 100644 --- a/packages/react-bootstrap-table2-toolkit/src/csv/exporter.js +++ b/packages/react-bootstrap-table2-toolkit/src/csv/exporter.js @@ -12,17 +12,21 @@ export const getMetaInfo = columns => export: column.csvExport === false ? false : true, row: Number(column.row) || 0, rowSpan: Number(column.rowSpan) || 1, - colSpan: Number(column.colSpan) || 1 + colSpan: Number(column.colSpan) || 1, + footer: column.footer, + footerFormatter: column.footerFormatter })) .filter(_ => _.export); export const transform = ( data, meta, - getValue, + columns, + _, { separator, - ignoreHeader + ignoreHeader, + ignoreFooter } ) => { const visibleColumns = meta.filter(m => m.export); @@ -37,7 +41,7 @@ export const transform = ( content += data .map((row, rowIndex) => visibleColumns.map((m) => { - let cellContent = getValue(row, m.field); + let cellContent = _.get(row, m.field); if (m.formatter) { cellContent = m.formatter(cellContent, row, rowIndex, m.formatExtraData); } @@ -47,6 +51,18 @@ export const transform = ( return cellContent; }).join(separator)).join('\n'); + if (!ignoreFooter) { + content += '\n'; + content += visibleColumns.map((m, i) => { + if (typeof m.footer === 'function') { + const columnData = _.pluck(data, columns[i].dataField); + return `"${m.footer(columnData, columns[i], i)}"`; + } else if (m.footerFormatter) { + return `"${m.footerFormatter(columns[i], i)}"`; + } + return `"${m.footer}"`; + }).join(separator); + } return content; }; diff --git a/packages/react-bootstrap-table2-toolkit/src/op/csv.js b/packages/react-bootstrap-table2-toolkit/src/op/csv.js index 5724559..6b04c4e 100644 --- a/packages/react-bootstrap-table2-toolkit/src/op/csv.js +++ b/packages/react-bootstrap-table2-toolkit/src/op/csv.js @@ -4,6 +4,7 @@ const csvDefaultOptions = { fileName: 'spreadsheet.csv', separator: ',', ignoreHeader: false, + ignoreFooter: true, noAutoBOM: true, blobType: 'text/plain;charset=utf-8', exportAll: true, @@ -46,7 +47,7 @@ export default Base => data = data.filter(row => !!selections.find(sel => row[keyField] === sel)); } - const content = transform(data, meta, this._.get, options); + const content = transform(data, meta, columns, this._, options); save(content, options); } };