From 5c52c18071ab590b65b8d4ec4d83c26908e04125 Mon Sep 17 00:00:00 2001 From: Alexzjt <1543042497@qq.com> Date: Tue, 24 Mar 2026 16:49:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=98=8E=E7=BB=86=E8=A1=A8=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=BA=8F=E5=8F=B7=E5=88=97=20formatter=20=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../s2-core/__tests__/bugs/issue-3332-spec.ts | 103 ++++++++++++++++++ .../src/utils/export/copy/table-copy.ts | 18 ++- 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 packages/s2-core/__tests__/bugs/issue-3332-spec.ts diff --git a/packages/s2-core/__tests__/bugs/issue-3332-spec.ts b/packages/s2-core/__tests__/bugs/issue-3332-spec.ts new file mode 100644 index 0000000000..888806692a --- /dev/null +++ b/packages/s2-core/__tests__/bugs/issue-3332-spec.ts @@ -0,0 +1,103 @@ +/** + * @description spec for issue #3332 + * https://github.com/antvis/S2/issues/3332 + * 明细表导出不支持序号的格式化 + */ +import { TableSheet } from '@/sheet-type'; +import { asyncGetAllPlainData } from '@/utils'; +import { slice } from 'lodash'; +import { data as originData } from 'tests/data/mock-dataset.json'; +import { LINE_SEPARATOR, SERIES_NUMBER_FIELD, TAB_SEPARATOR } from '../../src'; +import { assembleDataCfg, assembleOptions } from '../util'; +import { getContainer } from '../util/helpers'; + +describe('TableSheet Export Series Number Formatter Tests', () => { + const formatter = (value: number | string) => + String.fromCharCode(96 + Number(value)); + + const createSheetWithSeriesNumberFormatter = async () => { + const s2 = new TableSheet( + getContainer(), + assembleDataCfg({ + meta: [ + { + field: SERIES_NUMBER_FIELD, + name: '序号', + formatter, + }, + ], + fields: { + columns: ['province', 'city', 'type', 'sub_type', 'number'], + }, + data: slice(originData, 0, 5), + }), + assembleOptions({ + seriesNumber: { + enable: true, + }, + }), + ); + + await s2.render(); + + return s2; + }; + + // https://github.com/antvis/S2/issues/3332 + test('should apply series number formatter when exporting with formatOptions: true', async () => { + const s2 = await createSheetWithSeriesNumberFormatter(); + + const data = await asyncGetAllPlainData({ + sheetInstance: s2, + split: TAB_SEPARATOR, + formatOptions: true, + }); + + const rows = data.split(LINE_SEPARATOR); + + // 序号列应为格式化后的字母 a, b, c, d, e + for (let i = 1; i < rows.length; i++) { + const cols = rows[i].split(TAB_SEPARATOR); + + expect(cols[0]).toBe(formatter(i)); + } + }); + + test('should apply series number formatter when exporting async', async () => { + const s2 = await createSheetWithSeriesNumberFormatter(); + + const data = await asyncGetAllPlainData({ + sheetInstance: s2, + split: TAB_SEPARATOR, + formatOptions: true, + async: true, + }); + + const rows = data.split(LINE_SEPARATOR); + + for (let i = 1; i < rows.length; i++) { + const cols = rows[i].split(TAB_SEPARATOR); + + expect(cols[0]).toBe(formatter(i)); + } + }); + + test('should not apply series number formatter when formatOptions is false', async () => { + const s2 = await createSheetWithSeriesNumberFormatter(); + + const data = await asyncGetAllPlainData({ + sheetInstance: s2, + split: TAB_SEPARATOR, + formatOptions: false, + }); + + const rows = data.split(LINE_SEPARATOR); + + // formatOptions: false 时,序号列应为原始数字 + for (let i = 1; i < rows.length; i++) { + const cols = rows[i].split(TAB_SEPARATOR); + + expect(cols[0]).toBe(String(i)); + } + }); +}); diff --git a/packages/s2-core/src/utils/export/copy/table-copy.ts b/packages/s2-core/src/utils/export/copy/table-copy.ts index 41f07d087b..7a718ee6a0 100644 --- a/packages/s2-core/src/utils/export/copy/table-copy.ts +++ b/packages/s2-core/src/utils/export/copy/table-copy.ts @@ -66,7 +66,14 @@ class TableDataCellCopy extends BaseDataCellCopy { const field = node?.field; if (SERIES_NUMBER_FIELD === field && seriesNumber?.enable) { - return (i + 1).toString(); + const seriesValue = i + 1; + const formatter = this.getFormatter({ + field, + rowIndex: i, + colIndex: j, + }); + + return formatter(seriesValue); } const formatter = this.getFormatter({ @@ -114,7 +121,14 @@ class TableDataCellCopy extends BaseDataCellCopy { const field = colNode.field; if (SERIES_NUMBER_FIELD === field && seriesNumber?.enable) { - row.push((j + 1).toString()); + const seriesValue = j + 1; + const formatter = this.getFormatter({ + field, + rowIndex: j, + colIndex: i, + }); + + row.push(formatter(seriesValue) as string); // eslint-disable-next-line no-continue continue; }