diff --git a/packages/s2-core/__tests__/unit/utils/export/copy-spec.ts b/packages/s2-core/__tests__/unit/utils/export/copy-spec.ts index 2f554b5802..cb4eac2a0f 100644 --- a/packages/s2-core/__tests__/unit/utils/export/copy-spec.ts +++ b/packages/s2-core/__tests__/unit/utils/export/copy-spec.ts @@ -1,3 +1,4 @@ +import type { S2DataConfig } from '@antv/s2'; import { assembleDataCfg, assembleOptions, TOTALS_OPTIONS } from 'tests/util'; import { getContainer } from 'tests/util/helpers'; import { data as originalData, totalData } from 'tests/data/mock-dataset.json'; @@ -709,6 +710,195 @@ describe('Pivot Table Core Data Process', () => { }); }); +describe('Tree Table Core Data Process', () => { + let s2: PivotSheet; + + function setSelectedVisibleCell() { + const cell = s2.interaction + .getAllCells() + .filter(({ cellType }) => cellType === CellTypes.DATA_CELL); + + s2.interaction.changeState({ + cells: map(cell, getCellMeta), + stateName: InteractionStateName.SELECTED, + }); + } + + beforeEach(() => { + s2 = new PivotSheet( + getContainer(), + assembleDataCfg({ + meta: [], + fields: { + columns: ['type', 'sub_type'], + rows: ['province', 'city'], + values: ['number'], + }, + }), + assembleOptions({ + hierarchyType: 'tree', + interaction: { + enableCopy: true, + }, + totals: TOTALS_OPTIONS, + }), + ); + s2.render(); + }); + + it('should copy no data in tree mode', () => { + s2.interaction.changeState({ + cells: [], + stateName: InteractionStateName.SELECTED, + }); + const data = getSelectedData(s2); + expect(data).toBe(''); + }); + + it('should copy normal data in tree mode', () => { + setSelectedVisibleCell(); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + "18375 14043 32418 4826 5854 + 7789 5343 13132 945 1343 + 2367 632 2999 1304 1354 + 3877 7234 11111 1145 1523 + 4342 834 5176 1432 1634 + 7818 9473 17291 7495 10984 + 1723 2451 4174 2335 4004 + 1822 2244 4066 245 3077 + 1943 2333 4276 2457 3551 + 2330 2445 4775 2458 352 + 26193 23516 49709 12321 16838" + `); + }); + + it('should copy col data in grid tree', () => { + const cell = s2.interaction + .getAllCells() + .filter(({ cellType }) => cellType === CellTypes.COL_CELL)[0]; + + s2.interaction.changeState({ + cells: [getCellMeta(cell)], + stateName: InteractionStateName.SELECTED, + }); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + "18375 14043 32418 + 7789 5343 13132 + 2367 632 2999 + 3877 7234 11111 + 4342 834 5176 + 7818 9473 17291 + 1723 2451 4174 + 1822 2244 4066 + 1943 2333 4276 + 2330 2445 4775 + 26193 23516 49709" + `); + }); + + it('should copy row data in grid tree', () => { + const cell = s2.interaction + .getAllCells() + .filter(({ cellType }) => cellType === CellTypes.ROW_CELL)[0]; + + s2.interaction.changeState({ + cells: [getCellMeta(cell)], + stateName: InteractionStateName.SELECTED, + }); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + "18375 14043 32418 4826 5854 10680 43098 + 7789 5343 13132 945 1343 2288 15420 + 2367 632 2999 1304 1354 2658 5657 + 3877 7234 11111 1145 1523 2668 13779 + 4342 834 5176 1432 1634 3066 8242" + `); + }); + + it('should copy all data in tree mode', () => { + s2.interaction.changeState({ + stateName: InteractionStateName.ALL_SELECTED, + }); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + "18375 14043 32418 4826 5854 10680 43098 + 7789 5343 13132 945 1343 2288 15420 + 2367 632 2999 1304 1354 2658 5657 + 3877 7234 11111 1145 1523 2668 13779 + 4342 834 5176 1432 1634 3066 8242 + 7818 9473 17291 7495 10984 18479 35770 + 1723 2451 4174 2335 4004 6339 10513 + 1822 2244 4066 245 3077 3322 7388 + 1943 2333 4276 2457 3551 6008 10284 + 2330 2445 4775 2458 352 2810 7585 + 26193 23516 49709 12321 16838 29159 78868" + `); + }); + + it('should copy all data in tree mode with format', () => { + s2.setDataCfg({ + meta: [{ field: 'number', formatter: (v) => v + '元' }], + fields: { + columns: ['type', 'sub_type'], + rows: ['province', 'city'], + values: ['number'], + }, + } as S2DataConfig); + s2.setOptions({ + interaction: { + copyWithFormat: true, + }, + }); + s2.render(); + + setSelectedVisibleCell(); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + "18375元 14043元 32418 4826元 5854元 + 7789元 5343元 13132 945元 1343元 + 2367元 632元 2999 1304元 1354元 + 3877元 7234元 11111 1145元 1523元 + 4342元 834元 5176 1432元 1634元 + 7818元 9473元 17291 7495元 10984元 + 1723元 2451元 4174 2335元 4004元 + 1822元 2244元 4066 245元 3077元 + 1943元 2333元 4276 2457元 3551元 + 2330元 2445元 4775 2458元 352元 + 26193元 23516元 49709 12321元 16838元" + `); + }); + + it('should copy normal data with header in tree mode', () => { + s2.setOptions({ + interaction: { + copyWithHeader: true, + }, + }); + s2.render(); + + setSelectedVisibleCell(); + + expect(getSelectedData(s2)).toMatchInlineSnapshot(` + " 家具 家具 家具 办公用品 办公用品 + 桌子 沙发 小计 笔 纸张 + number number number number + 浙江省 18375 14043 32418 4826 5854 + 浙江省 7789 5343 13132 945 1343 + 浙江省 2367 632 2999 1304 1354 + 浙江省 3877 7234 11111 1145 1523 + 浙江省 4342 834 5176 1432 1634 + 四川省 7818 9473 17291 7495 10984 + 四川省 1723 2451 4174 2335 4004 + 四川省 1822 2244 4066 245 3077 + 四川省 1943 2333 4276 2457 3551 + 四川省 2330 2445 4775 2458 352 + 总计 26193 23516 49709 12321 16838" + `); + }); +}); + describe('List Table getCopyData', () => { let s2: TableSheet; beforeEach(() => { diff --git a/packages/s2-core/src/utils/export/copy.ts b/packages/s2-core/src/utils/export/copy.ts index 55133ee449..87af3c779f 100644 --- a/packages/s2-core/src/utils/export/copy.ts +++ b/packages/s2-core/src/utils/export/copy.ts @@ -87,7 +87,7 @@ const getValueFromMeta = ( colNode.isTotals || colNode.isTotalMeasure, }); - return cell[VALUE_FIELD]; + return cell?.[VALUE_FIELD] ?? ''; } const fieldId = getFiledIdFromMeta(meta.colIndex, spreadsheet); return displayData[meta.rowIndex]?.[fieldId]; @@ -337,7 +337,10 @@ const getDataMatrix = ( colNode.isTotals || colNode.isTotalMeasure, }); - return getFormat(colNode.colIndex, spreadsheet)(cellData[VALUE_FIELD]); + return getFormat( + colNode.colIndex, + spreadsheet, + )(cellData?.[VALUE_FIELD] ?? ''); }); }); }; @@ -383,7 +386,7 @@ const processPivotColSelected = ( ): Copyable => { const allRowLeafNodes = spreadsheet .getRowNodes() - .filter((node) => node.isLeaf); + .filter((node) => node.isLeaf || spreadsheet.isHierarchyTreeType()); const allColLeafNodes = spreadsheet .getColumnNodes() .filter((node) => node.isLeaf); @@ -436,7 +439,7 @@ const processPivotRowSelected = ( ): Copyable => { const allRowLeafNodes = spreadsheet .getRowNodes() - .filter((node) => node.isLeaf); + .filter((node) => node.isLeaf || spreadsheet.isHierarchyTreeType()); const allColLeafNodes = spreadsheet .getColumnNodes() .filter((node) => node.isLeaf); @@ -636,10 +639,6 @@ function getDataCellCopyable( const displayData = spreadsheet.dataSet.getDisplayDataSet(); - if (spreadsheet.isPivotMode() && spreadsheet.isHierarchyTreeType()) { - // 树状模式透视表之后实现 - return; - } if ( spreadsheet.interaction.getCurrentStateName() === InteractionStateName.ALL_SELECTED