From 0c921f4e5301b175240ca953dc57393a42e560f4 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Sun, 24 Nov 2024 22:18:23 +0800 Subject: [PATCH] feat(data-table): adds `get-csv-header` and `get-csv-cell` props, closes #6542 --- CHANGELOG.en-US.md | 1 + CHANGELOG.zh-CN.md | 1 + src/data-table/demos/enUS/index.demo-entry.md | 2 ++ src/data-table/demos/zhCN/index.demo-entry.md | 2 ++ src/data-table/index.ts | 1 + src/data-table/src/DataTable.tsx | 7 ++++++- src/data-table/src/interface.ts | 3 +++ src/data-table/src/publicTypes.ts | 8 ++++++++ src/data-table/src/utils.ts | 20 ++++++++++++++++--- 9 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/data-table/src/publicTypes.ts diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index b802c2b2661..d6d5560b4f5 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -23,6 +23,7 @@ - `n-progress`'s `color` prop supports gradient config. - `n-select` adds `font-weight` theme variable - `n-input` adds `font-weight` theme variable +- `n-data-table` adds `get-csv-header` and `get-csv-cell` props, closes [#6542](https://github.com/tusen-ai/naive-ui/issues/6542). ## 2.40.1 diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index b5af190e1a2..132474e30e7 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -23,6 +23,7 @@ - `n-progress` 的 `color` 属性支持渐变色配置 - `n-select` 新增 `font-weight` 主题变量 - `n-input` 新增 `font-weight` 主题变量 +- `n-data-table` 新增 `get-csv-header` 和 `get-csv-cell` 属性,关闭 [#6542](https://github.com/tusen-ai/naive-ui/issues/6542) ## 2.40.1 diff --git a/src/data-table/demos/enUS/index.demo-entry.md b/src/data-table/demos/enUS/index.demo-entry.md index 2b4530aa17a..c6c7a23c02a 100644 --- a/src/data-table/demos/enUS/index.demo-entry.md +++ b/src/data-table/demos/enUS/index.demo-entry.md @@ -82,6 +82,8 @@ export-csv.vue | expanded-row-keys | `Array` | `undefined` | Expanded row keys. | | | filter-icon-popover-props | `PopoverProps` | `{ trigger: click, placement: bottom }` | Filter icon's Popover attribute of the button, See [Popover props](popover#Popover-Props) | 2.39.0 | | flex-height | `boolean` | `false` | Whether to make table body's height auto fit table area height. Make it enabled will make `table-layout` always set to `'fixed'`. | | +| get-csv-cell | `(value: any, row: object, col: DataTableBaseColumn) => string` | `undefined` | Get CSV's cell content. | NEXT_VERSION | +| get-csv-header | `(cols: Array) => string` | `undefined` | Get CSV's header content. | NEXT_VERSION | | header-height | `number` | `28` | Header height value when `virtual-scroll-header` is enabled. | 2.40.0 | | height-for-row | `(rowData: object, index: number) => number` | `undefined` | Height configuration function for each row of the table. It must be used with `virtual-scroll-x`. If it's not configured, each rows height would be set to `min-row-height`. | 2.40.0 | | indent | `number` | `16` | Indent of row content when using tree data. | | diff --git a/src/data-table/demos/zhCN/index.demo-entry.md b/src/data-table/demos/zhCN/index.demo-entry.md index b88384e4205..2273a2a748a 100644 --- a/src/data-table/demos/zhCN/index.demo-entry.md +++ b/src/data-table/demos/zhCN/index.demo-entry.md @@ -93,6 +93,8 @@ rtl-debug.vue | expanded-row-keys | `Array` | `undefined` | 展开行的 key 值 | | | filter-icon-popover-props | `PopoverProps` | `{ trigger: click, placement: bottom }` | 过滤按钮的 Popover 属性,属性参考 [Popover props](popover#Popover-Props) | 2.39.0 | | flex-height | `boolean` | `false` | 是否让表格主体的高度自动适应整个表格区域的高度,打开这个选项会让 `table-layout` 始终为 `'fixed'` | | +| get-csv-cell | `(value: any, row: object, col: DataTableBaseColumn) => string` | `undefined` | 获取 CSV 的单元格数据 | NEXT_VERSION | +| get-csv-header | `(cols: Array) => string` | `undefined` | 获取 CSV 的 header | NEXT_VERSION | | header-height | `number` | `28` | 在开启 `virtual-scroll-header` 属性的情况下,表头的高度 | 2.40.0 | | height-for-row | `(rowData: object, index: number) => number` | `undefined` | 每行高度的配置函数,必须配合 `virtual-scroll-x` 使用,如果不进行配置,每一行的高度会被设为 `min-row-height` | 2.40.0 | | indent | `number` | `16` | 使用树形数据时行内容的缩进 | | diff --git a/src/data-table/index.ts b/src/data-table/index.ts index 8788cb8f11f..49b3b74fa51 100644 --- a/src/data-table/index.ts +++ b/src/data-table/index.ts @@ -22,3 +22,4 @@ export type { FilterState as DataTableFilterState, SortState as DataTableSortState } from './src/interface' +export * from './src/publicTypes' diff --git a/src/data-table/src/DataTable.tsx b/src/data-table/src/DataTable.tsx index 4895b6fd080..5a8783151bf 100644 --- a/src/data-table/src/DataTable.tsx +++ b/src/data-table/src/DataTable.tsx @@ -137,7 +137,12 @@ export default defineComponent({ const downloadCsv = (options?: CsvOptionsType): void => { const { fileName = 'data.csv', keepOriginalData = false } = options || {} const data = keepOriginalData ? props.data : rawPaginatedDataRef.value - const csvData = generateCsv(props.columns, data) + const csvData = generateCsv( + props.columns, + data, + props.getCsvCell, + props.getCsvHeader + ) const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8' }) const downloadUrl = URL.createObjectURL(blob) download( diff --git a/src/data-table/src/interface.ts b/src/data-table/src/interface.ts index 194626abc15..f788e920391 100644 --- a/src/data-table/src/interface.ts +++ b/src/data-table/src/interface.ts @@ -21,6 +21,7 @@ import type { DataTableTheme } from '../styles' import type { BaseLoadingExposedProps } from '../../_internal' import type { PopoverProps } from '../../popover' import type { ColItem, RowItem } from './use-group-header' +import type { DataTableGetCsvCell, DataTableGetCsvHeader } from './publicTypes' export const dataTableProps = { ...(useTheme.props as ThemeProps), @@ -129,6 +130,8 @@ export const dataTableProps = { >, renderExpandIcon: Function as PropType, spinProps: { type: Object as PropType, default: {} }, + getCsvCell: Function as PropType, + getCsvHeader: Function as PropType, onLoad: Function as PropType, 'onUpdate:page': [Function, Array] as PropType< PaginationProps['onUpdate:page'] diff --git a/src/data-table/src/publicTypes.ts b/src/data-table/src/publicTypes.ts new file mode 100644 index 00000000000..214602112ae --- /dev/null +++ b/src/data-table/src/publicTypes.ts @@ -0,0 +1,8 @@ +import type { TableBaseColumn } from './interface' + +export type DataTableGetCsvCell = ( + value: any, + rowData: object, + column: TableBaseColumn +) => string +export type DataTableGetCsvHeader = (column: TableBaseColumn) => string diff --git a/src/data-table/src/utils.ts b/src/data-table/src/utils.ts index b64b838e453..9ff32ec8154 100644 --- a/src/data-table/src/utils.ts +++ b/src/data-table/src/utils.ts @@ -13,6 +13,7 @@ import type { TableExpandColumn, TableSelectionColumn } from './interface' +import type { DataTableGetCsvCell, DataTableGetCsvHeader } from './publicTypes' export const SELECTION_COL_WIDTH = 40 export const EXPAND_COL_WIDTH = 40 @@ -205,17 +206,30 @@ function formatCsvCell(value: unknown): string { } } -export function generateCsv(columns: TableColumn[], data: RowData[]): string { +export function generateCsv( + columns: TableColumn[], + data: RowData[], + getCsvCell: DataTableGetCsvCell | undefined, + getCsvHeader: DataTableGetCsvHeader | undefined +): string { const exportableColumns = columns.filter( column => column.type !== 'expand' && column.type !== 'selection' && column.allowExport !== false ) - const header = exportableColumns.map((col: any) => col.title).join(',') + const header = exportableColumns + .map((col: any) => { + return getCsvHeader ? getCsvHeader(col) : col.title + }) + .join(',') const rows = data.map((row) => { return exportableColumns - .map((col: any) => formatCsvCell(row[col.key])) + .map((col: any) => { + return getCsvCell + ? getCsvCell(row[col.key], row, col) + : formatCsvCell(row[col.key]) + }) .join(',') }) return [header, ...rows].join('\n')