zmdms-webui 2.3.6 → 2.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { __assign } from '../_virtual/_tslib.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useRef, useState, useCallback, useMemo } from 'react';
3
+ import { useRef, useState, useCallback, useMemo, useImperativeHandle } from 'react';
4
4
  import { Spin } from 'antd';
5
5
  import './components/FilterPopover.js';
6
6
  import CellOverlay from './components/CellOverlay.js';
@@ -39,7 +39,7 @@ import { getTableColumns } from '../table/utils.js';
39
39
  import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
40
40
 
41
41
  function CanvasTable(props) {
42
- var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle, _m = props.mode, mode = _m === void 0 ? "index" : _m, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _o = props.isIndexMerge, isIndexMerge = _o === void 0 ? true : _o, _p = props.isSelectionMerge, isSelectionMerge = _p === void 0 ? false : _p, _q = props.renderMode, renderMode = _q === void 0 ? "object" : _q, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _r = props.summaryFixed, summaryFixed = _r === void 0 ? false : _r, _s = props.isAutoScrollY, isAutoScrollY = _s === void 0 ? false : _s, _t = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _t === void 0 ? 65 : _t, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap;
42
+ var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle, _m = props.mode, mode = _m === void 0 ? "index" : _m, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _o = props.isIndexMerge, isIndexMerge = _o === void 0 ? true : _o, _p = props.isSelectionMerge, isSelectionMerge = _p === void 0 ? false : _p, _q = props.renderMode, renderMode = _q === void 0 ? "object" : _q, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _r = props.summaryFixed, summaryFixed = _r === void 0 ? false : _r, _s = props.isAutoScrollY, isAutoScrollY = _s === void 0 ? false : _s, _t = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _t === void 0 ? 65 : _t, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _u = props.headerAlign, headerAlign = _u === void 0 ? "center" : _u, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig;
43
43
  var canvasRef = useRef(null);
44
44
  var containerRef = useRef(null);
45
45
  var filterPopoverRef = useRef(null);
@@ -61,15 +61,17 @@ function CanvasTable(props) {
61
61
  return String((_a = record[rowKey]) !== null && _a !== void 0 ? _a : index);
62
62
  }, [rowKey]);
63
63
  // 动态列配置
64
- var _u = useDynamicListByColumns(columns, {
64
+ var _v = useDynamicListByColumns(columns, {
65
65
  dynamicKey: dynamicKey,
66
66
  dynamicVersion: dynamicVersion,
67
67
  customDynamicListHandle: customDynamicListHandle,
68
- }), defaultDynamicList = _u.defaultDynamicList, currentDynamicList = _u.currentDynamicList, onCurrentListChange = _u.onCurrentListChange, dynamicSettingRef = _u.dynamicSettingRef;
68
+ }), defaultDynamicList = _v.defaultDynamicList, currentDynamicList = _v.currentDynamicList, onCurrentListChange = _v.onCurrentListChange, dynamicSettingRef = _v.dynamicSettingRef;
69
69
  // 根据动态列配置处理columns
70
70
  var dynamicColumns = useMemo(function () { return getTableColumns(columns, currentDynamicList); }, [columns, currentDynamicList]).columns;
71
71
  // 内部列宽状态(未开启动态配置时使用)
72
- var _v = useState({}), internalColumnWidths = _v[0], setInternalColumnWidths = _v[1];
72
+ var _w = useState({}), internalColumnWidths = _w[0], setInternalColumnWidths = _w[1];
73
+ // 跟踪用户手动调整过宽度的列(用于排除自动宽度分配)
74
+ var _x = useState(new Set()), manuallyResizedColumnKeys = _x[0], setManuallyResizedColumnKeys = _x[1];
73
75
  // 处理选中框列、序号列等
74
76
  var processedColumnsOld = useProcessedColumns({
75
77
  columns: columns,
@@ -81,30 +83,31 @@ function CanvasTable(props) {
81
83
  renderMode: renderMode,
82
84
  dynamicSettingRef: dynamicSettingRef,
83
85
  headerWrap: headerWrap,
86
+ headerAlign: headerAlign,
84
87
  });
85
88
  // 表格状态管理
86
- var _w = useTableState({
89
+ var _y = useTableState({
87
90
  dataSource: dataSource,
88
91
  columns: processedColumnsOld,
89
92
  rowSelection: rowSelection,
90
93
  onFilterChange: onFilterChange,
91
- }), state = _w.state, setState = _w.setState, processedDataSource = _w.processedDataSource, handleFilterChange = _w.handleFilterChange, closeFilterPopover = _w.closeFilterPopover, autoGeneratedFilters = _w.autoGeneratedFilters;
94
+ }), state = _y.state, setState = _y.setState, processedDataSource = _y.processedDataSource, handleFilterChange = _y.handleFilterChange, closeFilterPopover = _y.closeFilterPopover, autoGeneratedFilters = _y.autoGeneratedFilters;
92
95
  var order = useMemo(function () {
93
96
  return state.sortOrder && state.sortField
94
97
  ? { field: state.sortField, order: state.sortOrder }
95
98
  : undefined;
96
99
  }, [state.sortOrder, state.sortField]);
97
- var _x = useAutoMerge(processedDataSource, processedColumnsOld, {
100
+ var _z = useAutoMerge(processedDataSource, processedColumnsOld, {
98
101
  isAutoMerge: isAutoMerge,
99
102
  isDimensionDynamic: isDimensionDynamic,
100
103
  order: order,
101
104
  dimensionCustomSumKeys: dimensionCustomSumKeys,
102
- }), newDataSource = _x[0], processedColumns = _x[1];
105
+ }), newDataSource = _z[0], processedColumns = _z[1];
103
106
  // 生成合计行和最终数据源
104
- var _y = useSummaryRow({
107
+ var _0 = useSummaryRow({
105
108
  columns: processedColumns,
106
109
  dataSource: newDataSource,
107
- }), finalDataSource = _y.finalDataSource, hasSummaryRow = _y.hasSummaryRow;
110
+ }), finalDataSource = _0.finalDataSource, hasSummaryRow = _0.hasSummaryRow;
108
111
  // 自动高度计算(需要在容器尺寸计算之前)
109
112
  var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId);
110
113
  // 监听容器尺寸变化(提前计算,用于列宽自适应)
@@ -116,7 +119,10 @@ function CanvasTable(props) {
116
119
  var containerWidth = containerSize.width;
117
120
  var containerHeight = containerSize.height;
118
121
  // 计算列的渲染信息(使用容器宽度进行自适应填充)
119
- var columnRenderInfos = useMemo(function () { return calculateColumnRenderInfos(processedColumns, containerWidth); }, [processedColumns, containerWidth]);
122
+ // 手动调整过宽度的列不参与自动宽度分配
123
+ var columnRenderInfos = useMemo(function () {
124
+ return calculateColumnRenderInfos(processedColumns, containerWidth, manuallyResizedColumnKeys);
125
+ }, [processedColumns, containerWidth, manuallyResizedColumnKeys]);
120
126
  // 计算表头动态高度(支持wrap换行)
121
127
  // 注意:必须在 columnRenderInfos 计算之后,以便使用实际的列宽
122
128
  var calculatedHeaderHeight = useHeaderHeight({
@@ -137,7 +143,7 @@ function CanvasTable(props) {
137
143
  return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
138
144
  }, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
139
145
  // 计算滚动条指标
140
- var _z = useScrollbarMetrics({
146
+ var _1 = useScrollbarMetrics({
141
147
  containerWidth: containerWidth,
142
148
  containerHeight: containerHeight,
143
149
  totalWidth: totalWidth,
@@ -145,15 +151,15 @@ function CanvasTable(props) {
145
151
  headerHeight: calculatedHeaderHeight,
146
152
  scrollTop: 0,
147
153
  scrollLeft: 0,
148
- }), maxScrollTop = _z.maxScrollTop, maxScrollLeft = _z.maxScrollLeft;
154
+ }), maxScrollTop = _1.maxScrollTop, maxScrollLeft = _1.maxScrollLeft;
149
155
  // 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
150
- var _0 = useTableScroll({
156
+ var _2 = useTableScroll({
151
157
  canvasRef: canvasRef,
152
158
  containerRef: containerRef,
153
159
  maxScrollTop: maxScrollTop,
154
160
  maxScrollLeft: maxScrollLeft,
155
161
  onScroll: onScroll,
156
- }), scrollState = _0.scrollState, setScrollState = _0.setScrollState;
162
+ }), scrollState = _2.scrollState, setScrollState = _2.setScrollState;
157
163
  // 数据变化时重置滚动位置(筛选、排序、数据源更新等操作后)
158
164
  useScrollReset({
159
165
  dataSourceLength: dataSource.length,
@@ -174,17 +180,23 @@ function CanvasTable(props) {
174
180
  scrollLeft: scrollState.scrollLeft,
175
181
  }).actualMetrics;
176
182
  // 单元格框选
177
- var _1 = useTableSelection({
183
+ var _3 = useTableSelection({
178
184
  state: state,
179
185
  setState: setState,
180
186
  }),
181
187
  // selectionStartRef,
182
- startSelection = _1.startSelection, updateSelection = _1.updateSelection, extendSelection = _1.extendSelection;
188
+ startSelection = _3.startSelection, updateSelection = _3.updateSelection, extendSelection = _3.extendSelection;
183
189
  // 处理列宽调整
184
190
  var handleColumnResize = useCallback(function (columnKey, newWidth) {
185
191
  var _a;
186
192
  // 先调用外部回调(用户可以监听列宽变化)
187
193
  onColumnResize === null || onColumnResize === void 0 ? void 0 : onColumnResize(columnKey, newWidth);
194
+ // 记录用户手动调整过的列
195
+ setManuallyResizedColumnKeys(function (prev) {
196
+ var newSet = new Set(prev);
197
+ newSet.add(columnKey);
198
+ return newSet;
199
+ });
188
200
  if (dynamicKey && currentDynamicList) {
189
201
  // 开启了动态配置:更新到动态配置中
190
202
  var newList = currentDynamicList.map(function (item) { return (__assign({}, item)); });
@@ -228,13 +240,13 @@ function CanvasTable(props) {
228
240
  onCurrentListChange,
229
241
  ]);
230
242
  // 列宽调整
231
- var _2 = useColumnResize({
243
+ var _4 = useColumnResize({
232
244
  columnRenderInfos: columnRenderInfos,
233
245
  containerWidth: containerWidth,
234
246
  headerHeight: calculatedHeaderHeight,
235
247
  scrollLeft: scrollState.scrollLeft,
236
248
  onColumnResize: handleColumnResize,
237
- }), resizeState = _2.resizeState, checkResizeHandle = _2.checkResizeHandle, startResize = _2.startResize, updateResize = _2.updateResize, endResize = _2.endResize, setHoverResizeColumn = _2.setHoverResizeColumn, getColumnWidth = _2.getColumnWidth, RESIZE_HANDLE_WIDTH = _2.RESIZE_HANDLE_WIDTH;
249
+ }), resizeState = _4.resizeState, checkResizeHandle = _4.checkResizeHandle, startResize = _4.startResize, updateResize = _4.updateResize, endResize = _4.endResize, setHoverResizeColumn = _4.setHoverResizeColumn, getColumnWidth = _4.getColumnWidth, RESIZE_HANDLE_WIDTH = _4.RESIZE_HANDLE_WIDTH;
238
250
  // 复制到剪贴板
239
251
  var getSelectedCellsText = useCopyToClipboard({
240
252
  cellSelection: state.cellSelection,
@@ -251,13 +263,17 @@ function CanvasTable(props) {
251
263
  });
252
264
  }
253
265
  }, [getSelectedCellsText]);
266
+ // 过滤勾选框和index行给导出用
267
+ var exportColumns = useMemo(function () {
268
+ return processedColumns.filter(function (item) { return !item.key.includes("__"); });
269
+ }, [processedColumns]);
254
270
  // Excel导出功能
255
271
  var exportExcel = useExcelExport(processedDataSource, {
256
- columns: processedColumns,
272
+ columns: exportColumns,
257
273
  isAutoMerge: isAutoMerge,
258
274
  });
259
275
  // 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
260
- var _3 = useTableInteraction({
276
+ var _5 = useTableInteraction({
261
277
  state: state,
262
278
  setState: setState,
263
279
  scrollState: scrollState,
@@ -303,7 +319,7 @@ function CanvasTable(props) {
303
319
  fixedRowsCount: fixedRowsCount,
304
320
  fixedRowsConfig: fixedRowsConfig,
305
321
  summaryFixed: summaryFixed,
306
- }), handleCanvasMouseDown = _3.handleCanvasMouseDown, handleCanvasMouseMove = _3.handleCanvasMouseMove, handleCanvasMouseUp = _3.handleCanvasMouseUp, handleCanvasMouseLeave = _3.handleCanvasMouseLeave, handleCanvasContextMenu = _3.handleCanvasContextMenu;
322
+ }), handleCanvasMouseDown = _5.handleCanvasMouseDown, handleCanvasMouseMove = _5.handleCanvasMouseMove, handleCanvasMouseUp = _5.handleCanvasMouseUp, handleCanvasMouseLeave = _5.handleCanvasMouseLeave, handleCanvasContextMenu = _5.handleCanvasContextMenu;
307
323
  // 渲染表格
308
324
  useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
309
325
  state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, baseHeaderHeight: headerHeight, // 传入原始基础高度用于计算每层高度
@@ -365,6 +381,73 @@ function CanvasTable(props) {
365
381
  isVisible: state.badgePopover.visible,
366
382
  onClose: handleCloseBadgePopover,
367
383
  });
384
+ // 暴露给外部的方法
385
+ useImperativeHandle(tableRefHandle, function () { return ({
386
+ /** 获取当前表格的配置信息(动态列配置) */
387
+ getDynamicList: function () {
388
+ return currentDynamicList || [];
389
+ },
390
+ /** 动态列配置重置 */
391
+ onResetDynamicList: function () {
392
+ var _a, _b;
393
+ (_b = (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.resetList) === null || _b === void 0 ? void 0 : _b.call(_a);
394
+ },
395
+ /** 动态列配置设置 */
396
+ onSetDynamicList: function (list) {
397
+ var _a, _b;
398
+ (_b = (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.updateList) === null || _b === void 0 ? void 0 : _b.call(_a, list);
399
+ },
400
+ /** 导出Excel */
401
+ exportExcel: exportExcel,
402
+ /** 获取表格容器 */
403
+ getContainer: function () { return containerRef.current; },
404
+ /** 全屏展示表格 */
405
+ toggleFullScreen: function () {
406
+ var _a;
407
+ (_a = tableMenuRef.current) === null || _a === void 0 ? void 0 : _a.toggleFullscreen();
408
+ },
409
+ /** 获取选中的行keys */
410
+ getSelectedRowKeys: function () {
411
+ return state.selectedRowKeys;
412
+ },
413
+ /** 设置选中的行keys */
414
+ setSelectedRowKeys: function (keys) {
415
+ setState(function (prev) { return (__assign(__assign({}, prev), { selectedRowKeys: keys })); });
416
+ },
417
+ /** 滚动到指定位置 */
418
+ scrollTo: function (params) {
419
+ setScrollState(function (prev) { return (__assign(__assign({}, prev), { scrollLeft: params.x !== undefined ? params.x : prev.scrollLeft, scrollTop: params.y !== undefined ? params.y : prev.scrollTop })); });
420
+ },
421
+ /** 获取当前排序状态 */
422
+ getSortState: function () {
423
+ return {
424
+ field: state.sortField,
425
+ order: state.sortOrder,
426
+ };
427
+ },
428
+ /** 获取当前过滤状态 */
429
+ getFilterState: function () {
430
+ return state.filters;
431
+ },
432
+ /** 清除排序 */
433
+ clearSort: function () {
434
+ setState(function (prev) { return (__assign(__assign({}, prev), { sortField: null, sortOrder: null })); });
435
+ },
436
+ /** 清除过滤 */
437
+ clearFilter: function () {
438
+ setState(function (prev) { return (__assign(__assign({}, prev), { filters: {} })); });
439
+ },
440
+ }); }, [
441
+ currentDynamicList,
442
+ dynamicSettingRef,
443
+ exportExcel,
444
+ state.selectedRowKeys,
445
+ state.sortField,
446
+ state.sortOrder,
447
+ state.filters,
448
+ setState,
449
+ setScrollState,
450
+ ]);
368
451
  return (jsx(Spin, __assign({ spinning: loading }, { children: jsxs("div", __assign({ ref: containerRef, id: canvasTableId, className: "canvas-table-container ".concat(className || ""), tabIndex: 0, style: __assign(__assign({}, style), { position: "relative", width: width || "100%", height: containerHeight, overflow: "hidden", touchAction: "none", outline: "none" }) }, { children: [jsx("canvas", { ref: canvasRef, onMouseDown: handleCanvasMouseDown, onMouseMove: handleCanvasMouseMove, onMouseUp: handleCanvasMouseUp, onMouseLeave: handleCanvasMouseLeave, onContextMenu: handleCanvasContextMenu, style: {
369
452
  display: "block",
370
453
  // cursor 由 useTableInteraction 动态管理
@@ -374,7 +457,9 @@ function CanvasTable(props) {
374
457
  WebkitFontSmoothing: "antialiased",
375
458
  MozOsxFontSmoothing: "grayscale",
376
459
  textRendering: "optimizeLegibility",
377
- } }), dynamicKey ? (jsx(DynamicSetting, { parentDynamicKey: TABLE_DYNAMIC_KEY, dynamicKey: dynamicKey, defaultList: defaultDynamicList, onCurrentListChange: onCurrentListChange, ref: dynamicSettingRef, hiddenOperationIcon: true, isMore: true, isFixed: true, isDimensionDynamic: isDimensionDynamic })) : null, jsx(EmptyPlaceholder, { visible: finalDataSource.length === 0, text: emptyText, headerHeight: calculatedHeaderHeight }), jsx(HeaderOverlay, { overlays: headerOverlays }), jsx(CellOverlay, { overlays: cellOverlays }), filterPopoverElement, jsx(Tooltip, { visible: state.tooltip.visible, content: state.tooltip.content, position: state.tooltip.position }), jsx(BadgePopover, { visible: state.badgePopover.visible, content: state.badgePopover.content, position: state.badgePopover.position, popoverRef: badgePopoverRef }), menuId ? (jsx(CanvasTableMenu, { menuId: menuId, containerRef: containerRef, isFullscreenHandle: isFullscreenHandle, tableMenuRef: tableMenuRef, onCopy: handleCopy, onExport: dynamicKey ? exportExcel : undefined })) : null] })) })));
460
+ } }), dynamicKey ? (jsx(DynamicSetting, { parentDynamicKey: TABLE_DYNAMIC_KEY, dynamicKey: dynamicKey, defaultList: defaultDynamicList, onCurrentListChange: onCurrentListChange, ref: dynamicSettingRef, hiddenOperationIcon: true, isMore: true, isFixed: true, isDimensionDynamic: isDimensionDynamic })) : null, jsx(EmptyPlaceholder, { visible: finalDataSource.length === 0, text: emptyText, headerHeight: calculatedHeaderHeight }), jsx(HeaderOverlay, { overlays: headerOverlays }), jsx(CellOverlay, { overlays: cellOverlays }), filterPopoverElement, jsx(Tooltip, { visible: state.tooltip.visible, content: state.tooltip.content, position: state.tooltip.position }), jsx(BadgePopover, { visible: state.badgePopover.visible, content: state.badgePopover.content, position: state.badgePopover.position, popoverRef: badgePopoverRef }), menuId ? (jsx(CanvasTableMenu, { menuId: menuId, containerRef: containerRef, isFullscreenHandle: isFullscreenHandle, tableMenuRef: tableMenuRef, onCopy: handleCopy, onExport: function () {
461
+ return exportExcel((exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.fileName) || "表格数据.xlsx", __assign({}, exportExcelConfig));
462
+ } })) : null] })) })));
378
463
  }
379
464
 
380
465
  export { CanvasTable as default };
@@ -32,8 +32,7 @@ var CanvasTableMenu = function (_a) {
32
32
  break;
33
33
  }
34
34
  case "export": {
35
- var fileName = "\u8868\u683C\u6570\u636E_".concat(new Date().toLocaleDateString());
36
- onExport === null || onExport === void 0 ? void 0 : onExport(fileName);
35
+ onExport === null || onExport === void 0 ? void 0 : onExport();
37
36
  break;
38
37
  }
39
38
  }
@@ -1,14 +1,8 @@
1
1
  import { __spreadArray } from '../../_virtual/_tslib.js';
2
2
  import { useState, useEffect } from 'react';
3
3
  import { getMaxDepth, calculateLayerHeights } from '../utils/multiHeaderHelpers.js';
4
+ import { FONT_SIZE, FONT_FAMILY, LINE_HEIGHT, TEXT_PADDING, FILTER_ICON_WIDTH, SORT_ICON_WIDTH, ICON_SPACING } from '../utils/constants.js';
4
5
 
5
- var FONT_SIZE = 13;
6
- var FONT_FAMILY = '"Microsoft YaHei", 微软雅黑, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
7
- var LINE_HEIGHT = 20;
8
- var FILTER_ICON_WIDTH = 15;
9
- var SORT_ICON_WIDTH = 15;
10
- var ICON_SPACING = 4;
11
- var TEXT_PADDING = 5;
12
6
  /**
13
7
  * 计算文本在给定宽度下需要的行数
14
8
  */
@@ -94,9 +88,10 @@ var useHeaderHeight = function (params) {
94
88
  var columnWidth = ((_a = columnRenderInfos === null || columnRenderInfos === void 0 ? void 0 : columnRenderInfos[index]) === null || _a === void 0 ? void 0 : _a.width) || column.width || 100;
95
89
  return calculateColumnLines(ctx, column, columnWidth);
96
90
  }), false));
97
- // 基础高度 + (额外行数 * 行高)
91
+ // 当有换行时:上边距(5px) + 行数 * 行高 + 下边距(5px)
92
+ // 当没有换行时:使用原始的 headerHeight
98
93
  return maxLines > 1
99
- ? headerHeight + (maxLines - 1) * LINE_HEIGHT
94
+ ? 10 + maxLines * LINE_HEIGHT // 上下边距各5px,共10px
100
95
  : headerHeight;
101
96
  };
102
97
  setCalculatedHeight(calculateHeight());
@@ -16,7 +16,7 @@ import '../../node_modules/screenfull/index.js';
16
16
  import ColumnDynamic from '../components/ColumnDynamic.js';
17
17
 
18
18
  var useProcessedColumns = function (params) {
19
- var columns = params.columns, dynamicColumns = params.dynamicColumns, mode = params.mode, rowSelection = params.rowSelection, internalColumnWidths = params.internalColumnWidths, dynamicKey = params.dynamicKey, _a = params.renderMode, renderMode = _a === void 0 ? "object" : _a, dynamicSettingRef = params.dynamicSettingRef, headerWrap = params.headerWrap;
19
+ var columns = params.columns, dynamicColumns = params.dynamicColumns, mode = params.mode, rowSelection = params.rowSelection, internalColumnWidths = params.internalColumnWidths, dynamicKey = params.dynamicKey, _a = params.renderMode, renderMode = _a === void 0 ? "object" : _a, dynamicSettingRef = params.dynamicSettingRef, headerWrap = params.headerWrap, _b = params.headerAlign, headerAlign = _b === void 0 ? "center" : _b;
20
20
  return useMemo(function () {
21
21
  var cols = __spreadArray([], (dynamicColumns || columns), true);
22
22
  // 添加序号列
@@ -62,11 +62,19 @@ var useProcessedColumns = function (params) {
62
62
  }
63
63
  // 应用内部列宽状态(未开启动态配置时)
64
64
  if (!dynamicKey && Object.keys(internalColumnWidths).length > 0) {
65
- cols.forEach(function (col) {
66
- if (col.key && internalColumnWidths[col.key]) {
67
- col.width = internalColumnWidths[col.key];
68
- }
69
- });
65
+ // 递归应用列宽
66
+ var applyColumnWidths_1 = function (columns) {
67
+ columns.forEach(function (col) {
68
+ if (col.key && internalColumnWidths[col.key]) {
69
+ col.width = internalColumnWidths[col.key];
70
+ }
71
+ // 递归处理子列(多级表头)
72
+ if (col.children && col.children.length > 0) {
73
+ applyColumnWidths_1(col.children);
74
+ }
75
+ });
76
+ };
77
+ applyColumnWidths_1(cols);
70
78
  }
71
79
  // 验证动态列配置
72
80
  if (dynamicKey) {
@@ -79,7 +87,7 @@ var useProcessedColumns = function (params) {
79
87
  }
80
88
  // 处理render函数
81
89
  return cols.map(function (col) {
82
- return processColumnRender(col, renderMode, headerWrap);
90
+ return processColumnRender(col, renderMode, headerWrap, headerAlign);
83
91
  });
84
92
  }, [
85
93
  dynamicColumns,
@@ -90,6 +98,8 @@ var useProcessedColumns = function (params) {
90
98
  internalColumnWidths,
91
99
  renderMode,
92
100
  dynamicSettingRef,
101
+ headerWrap,
102
+ headerAlign,
93
103
  ]);
94
104
  };
95
105
 
@@ -22,15 +22,8 @@ var useSummaryRow = function (params) {
22
22
  if (!hasSummary)
23
23
  return null;
24
24
  var summaryRecord = {};
25
- // 找到第一个数据列(非序号列、非选择框列)
26
- var firstDataColIndex = -1;
27
- for (var i = 0; i < leafColumns.length; i++) {
28
- var col = leafColumns[i];
29
- if (col.key !== "__index__" && col.key !== "__selection__") {
30
- firstDataColIndex = i;
31
- break;
32
- }
33
- }
25
+ // 找到第一个列(包括序号列、选择框列)
26
+ var firstColIndex = leafColumns.length > 0 ? 0 : -1;
34
27
  leafColumns.forEach(function (column, colIndex) {
35
28
  var dataIndex = column.dataIndex || column.key;
36
29
  if (column.isSummary) {
@@ -60,8 +53,8 @@ var useSummaryRow = function (params) {
60
53
  }
61
54
  summaryRecord[dataIndex] = formattedSum;
62
55
  }
63
- else if (colIndex === firstDataColIndex) {
64
- // 第一个数据列显示"合计"
56
+ else if (colIndex === firstColIndex) {
57
+ // 第一列显示"合计"(可以是序号列、选择框列或数据列)
65
58
  summaryRecord[dataIndex] = "合计";
66
59
  }
67
60
  else {
@@ -129,7 +129,6 @@ var useTableRender = function (params) {
129
129
  ctx.fillStyle = COLORS.text;
130
130
  ctx.font = "".concat(FONT_WEIGHT, " ").concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
131
131
  ctx.textBaseline = "middle";
132
- var textX = drawX + 5;
133
132
  var textY = headerHeight / 2;
134
133
  // 绘制选择框
135
134
  if (column.key === "__selection__") {
@@ -142,26 +141,65 @@ var useTableRender = function (params) {
142
141
  else {
143
142
  // 计算图标占用的宽度
144
143
  var iconArea = calculateIconArea(column, width);
145
- // 计算文本可用宽度(左边距5px + 图标宽度 )
146
- var textMaxWidth = width - 5 - iconArea.iconsWidth;
144
+ // 确定表头对齐方式,优先使用列的 headerAlign,其次是 align,最后是默认值
145
+ var headerAlign = column.headerAlign || column.align || "center";
147
146
  // 绘制文本(如果 title 是 React 元素,跳过Canvas渲染,在覆盖层中渲染)
148
147
  if (!isValidElement(column.title)) {
149
148
  var titleText = String(column.title || "");
149
+ // 根据对齐方式和图标情况设置文本位置
150
+ var textX_1;
151
+ var textMaxWidth = void 0;
152
+ if (iconArea.iconsWidth > 0) {
153
+ // 有图标时,根据headerAlign调整文本位置和最大宽度
154
+ if (headerAlign === "right") {
155
+ ctx.textAlign = "right";
156
+ textX_1 = drawX + width - 5 - iconArea.iconsWidth;
157
+ textMaxWidth = width - 10 - iconArea.iconsWidth;
158
+ }
159
+ else if (headerAlign === "center") {
160
+ ctx.textAlign = "center";
161
+ textX_1 = drawX + (width - iconArea.iconsWidth) / 2;
162
+ textMaxWidth = width - 10 - iconArea.iconsWidth;
163
+ }
164
+ else {
165
+ ctx.textAlign = "left";
166
+ textX_1 = drawX + 5;
167
+ textMaxWidth = width - 5 - iconArea.iconsWidth;
168
+ }
169
+ }
170
+ else {
171
+ // 没有图标时,根据headerAlign设置对齐方式
172
+ if (headerAlign === "left") {
173
+ ctx.textAlign = "left";
174
+ textX_1 = drawX + 5;
175
+ textMaxWidth = width - 10;
176
+ }
177
+ else if (headerAlign === "right") {
178
+ ctx.textAlign = "right";
179
+ textX_1 = drawX + width - 5;
180
+ textMaxWidth = width - 10;
181
+ }
182
+ else {
183
+ ctx.textAlign = "center";
184
+ textX_1 = drawX + width / 2;
185
+ textMaxWidth = width - 10;
186
+ }
187
+ }
150
188
  // 根据 ellipsis 和 wrap 属性处理文本
151
189
  if (column.wrap) {
152
190
  // 换行显示(支持\n和自动换行)
153
191
  var lines = wrapText(ctx, titleText, textMaxWidth);
154
- var lineHeight_1 = 20;
192
+ var lineHeight_1 = FONT_SIZE + 5; // 字体大小 + 行间距5px
155
193
  var startY_1 = textY - ((lines.length - 1) * lineHeight_1) / 2;
156
194
  lines.forEach(function (line, index) {
157
195
  var lineY = startY_1 + index * lineHeight_1;
158
- ctx.fillText(line, textX, lineY);
196
+ ctx.fillText(line, textX_1, lineY);
159
197
  });
160
198
  }
161
199
  else {
162
200
  // 默认截断显示
163
201
  var truncatedText = truncateText(ctx, titleText, textMaxWidth);
164
- ctx.fillText(truncatedText, textX, textY);
202
+ ctx.fillText(truncatedText, textX_1, textY);
165
203
  }
166
204
  }
167
205
  // 绘制筛选图标(最右侧,距离右边5px)
@@ -178,6 +216,7 @@ var useTableRender = function (params) {
178
216
  drawSortIcon(ctx, iconX, textY, column.key === state.sortField ? state.sortOrder : null);
179
217
  }
180
218
  }
219
+ ctx.textAlign = "left"; // 重置对齐方式
181
220
  ctx.restore();
182
221
  // 绘制表头列之间的边框
183
222
  if (bordered) {
@@ -286,44 +325,73 @@ var useTableRender = function (params) {
286
325
  var iconArea = shouldShowIcons
287
326
  ? calculateIconArea(column, width)
288
327
  : { hasOrder: false, hasFilter: false, iconsWidth: 0 };
289
- // 如果是最末级且有图标,文本左对齐;否则居中
328
+ // 确定表头对齐方式,优先使用列的 headerAlign,其次是 align,最后是默认值
329
+ var headerAlign = column.headerAlign || column.align || "center";
330
+ // 如果是最末级且有图标,需要调整对齐方式
290
331
  if (isLastLevel && iconArea.iconsWidth > 0) {
291
- ctx.textAlign = "left";
292
- var textX_1 = drawX + 5;
293
- var textMaxWidth = width - 5 - iconArea.iconsWidth;
332
+ // 有图标时,根据headerAlign调整文本位置和最大宽度
333
+ var textX_2;
334
+ var textMaxWidth = void 0;
335
+ if (headerAlign === "right") {
336
+ ctx.textAlign = "right";
337
+ textX_2 = drawX + width - 5 - iconArea.iconsWidth;
338
+ textMaxWidth = width - 10 - iconArea.iconsWidth;
339
+ }
340
+ else if (headerAlign === "center") {
341
+ ctx.textAlign = "center";
342
+ textX_2 = drawX + (width - iconArea.iconsWidth) / 2;
343
+ textMaxWidth = width - 10 - iconArea.iconsWidth;
344
+ }
345
+ else {
346
+ ctx.textAlign = "left";
347
+ textX_2 = drawX + 5;
348
+ textMaxWidth = width - 5 - iconArea.iconsWidth;
349
+ }
294
350
  // 根据 wrap 属性处理文本
295
351
  if (column.wrap) {
296
352
  // 换行显示(支持\n和自动换行)
297
353
  var lines = wrapText(ctx, titleText, textMaxWidth);
298
- var lineHeight_2 = 20;
354
+ var lineHeight_2 = FONT_SIZE + 5; // 字体大小 + 行间距5px
299
355
  var startY_2 = textY - ((lines.length - 1) * lineHeight_2) / 2;
300
356
  lines.forEach(function (line, index) {
301
357
  var lineY = startY_2 + index * lineHeight_2;
302
- ctx.fillText(line, textX_1, lineY);
358
+ ctx.fillText(line, textX_2, lineY);
303
359
  });
304
360
  }
305
361
  else {
306
362
  var truncated = truncateText(ctx, titleText, textMaxWidth);
307
- ctx.fillText(truncated, textX_1, textY);
363
+ ctx.fillText(truncated, textX_2, textY);
308
364
  }
309
365
  }
310
366
  else {
311
- ctx.textAlign = "center";
312
- var textX_2 = drawX + width / 2;
367
+ // 没有图标时,根据headerAlign设置对齐方式
368
+ var textX_3;
369
+ if (headerAlign === "left") {
370
+ ctx.textAlign = "left";
371
+ textX_3 = drawX + 5;
372
+ }
373
+ else if (headerAlign === "right") {
374
+ ctx.textAlign = "right";
375
+ textX_3 = drawX + width - 5;
376
+ }
377
+ else {
378
+ ctx.textAlign = "center";
379
+ textX_3 = drawX + width / 2;
380
+ }
313
381
  // 根据 wrap 属性处理文本
314
382
  if (column.wrap) {
315
383
  // 换行显示(支持\n和自动换行)
316
384
  var lines = wrapText(ctx, titleText, width - 10); // 左右各5px
317
- var lineHeight_3 = 20;
385
+ var lineHeight_3 = FONT_SIZE + 5; // 字体大小 + 行间距5px
318
386
  var startY_3 = textY - ((lines.length - 1) * lineHeight_3) / 2;
319
387
  lines.forEach(function (line, index) {
320
388
  var lineY = startY_3 + index * lineHeight_3;
321
- ctx.fillText(line, textX_2, lineY);
389
+ ctx.fillText(line, textX_3, lineY);
322
390
  });
323
391
  }
324
392
  else {
325
393
  var truncated = truncateText(ctx, titleText, width - 10); // 左右各5px
326
- ctx.fillText(truncated, textX_2, textY);
394
+ ctx.fillText(truncated, textX_3, textY);
327
395
  }
328
396
  }
329
397
  // 绘制筛选图标(仅在最末级表头显示)
@@ -533,10 +601,30 @@ var useTableRender = function (params) {
533
601
  }
534
602
  // 单元格内容
535
603
  if (column.key === "__selection__") {
536
- var checkboxProps = ((_a = rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.getCheckboxProps) === null || _a === void 0 ? void 0 : _a.call(rowSelection, record)) || {};
537
- var disabled = checkboxProps.disabled || false;
538
- // 对于合并单元格,使用合并后的单元格高度进行垂直居中
539
- drawCheckbox(ctx, drawX + width / 2, y + cellHeight / 2, isSelected, disabled, false);
604
+ // 检查是否是合计行
605
+ var isSummaryRow = record[IS_SUMMARY];
606
+ if (!isSummaryRow) {
607
+ // 非合计行显示选择框
608
+ var checkboxProps = ((_a = rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.getCheckboxProps) === null || _a === void 0 ? void 0 : _a.call(rowSelection, record)) || {};
609
+ var disabled = checkboxProps.disabled || false;
610
+ // 对于合并单元格,使用合并后的单元格高度进行垂直居中
611
+ drawCheckbox(ctx, drawX + width / 2, y + cellHeight / 2, isSelected, disabled, false);
612
+ }
613
+ else {
614
+ // 合计行选择框列显示文本(比如"合计")
615
+ var dataIndex = column.dataIndex || column.key;
616
+ var cellValue = record[dataIndex];
617
+ var cellText = formatCellValue(cellValue, column);
618
+ if (cellText) {
619
+ ctx.fillStyle = COLORS.text;
620
+ ctx.font = "bold ".concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
621
+ ctx.textBaseline = "middle";
622
+ ctx.textAlign = "center";
623
+ var textX = drawX + width / 2;
624
+ var textY = y + cellHeight / 2;
625
+ ctx.fillText(cellText, textX, textY);
626
+ }
627
+ }
540
628
  }
541
629
  else {
542
630
  var dataIndex = column.dataIndex || column.key;
@@ -584,14 +672,14 @@ var useTableRender = function (params) {
584
672
  : "".concat(FONT_WEIGHT, " ").concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
585
673
  ctx.textBaseline = "middle";
586
674
  var align = column.align || "left";
587
- var textX_3 = drawX + 5;
675
+ var textX_4 = drawX + 5;
588
676
  if (align === "center") {
589
677
  ctx.textAlign = "center";
590
- textX_3 = drawX + width / 2;
678
+ textX_4 = drawX + width / 2;
591
679
  }
592
680
  else if (align === "right") {
593
681
  ctx.textAlign = "right";
594
- textX_3 = drawX + width - 5;
682
+ textX_4 = drawX + width - 5;
595
683
  }
596
684
  else {
597
685
  ctx.textAlign = "left";
@@ -601,9 +689,23 @@ var useTableRender = function (params) {
601
689
  var ellipsis = column.ellipsis !== false; // 默认为true
602
690
  var wrap = column.wrap === true; // 默认为false
603
691
  if (wrap) {
604
- // 换行显示
605
- var lines = wrapText(ctx, cellText, maxWidth);
606
- var lineHeight_4 = FONT_SIZE + 4; // 行高
692
+ // 换行显示,最多显示2行
693
+ var allLines = wrapText(ctx, cellText, maxWidth);
694
+ var maxLines = 2; // 限制最多显示2行
695
+ var lines = allLines.slice(0, maxLines);
696
+ // 如果超过2行,在第2行末尾强制添加省略号
697
+ if (allLines.length > maxLines && lines.length === maxLines) {
698
+ // 确保第2行有足够空间显示省略号
699
+ var lastLine = lines[maxLines - 1];
700
+ var ellipsisText = "...";
701
+ // 如果最后一行加上省略号会超出宽度,需要截断
702
+ while (lastLine.length > 0 &&
703
+ ctx.measureText(lastLine + ellipsisText).width > maxWidth) {
704
+ lastLine = lastLine.slice(0, -1);
705
+ }
706
+ lines[maxLines - 1] = lastLine + ellipsisText;
707
+ }
708
+ var lineHeight_4 = FONT_SIZE + 5; // 字体大小 + 行间距5px
607
709
  var totalHeight = lines.length * lineHeight_4;
608
710
  // 使用合并后的单元格高度计算垂直居中位置
609
711
  var startY_4 = y + (cellHeight - totalHeight) / 2 + lineHeight_4 / 2;
@@ -611,7 +713,7 @@ var useTableRender = function (params) {
611
713
  var lineY = startY_4 + lineIndex * lineHeight_4;
612
714
  // 只绘制在单元格可见区域内的文本
613
715
  if (lineY >= y && lineY <= y + cellHeight) {
614
- ctx.fillText(line, textX_3, lineY);
716
+ ctx.fillText(line, textX_4, lineY);
615
717
  }
616
718
  });
617
719
  }
@@ -619,12 +721,12 @@ var useTableRender = function (params) {
619
721
  // 省略显示 - 使用合并后的单元格高度
620
722
  var textY = y + cellHeight / 2;
621
723
  var truncatedText = truncateText(ctx, cellText, maxWidth);
622
- ctx.fillText(truncatedText, textX_3, textY);
724
+ ctx.fillText(truncatedText, textX_4, textY);
623
725
  }
624
726
  else {
625
727
  // 不处理,直接显示 - 使用合并后的单元格高度
626
728
  var textY = y + cellHeight / 2;
627
- ctx.fillText(cellText, textX_3, textY);
729
+ ctx.fillText(cellText, textX_4, textY);
628
730
  }
629
731
  if (column.badge && !isSummaryRow) {
630
732
  var badgeProps = typeof column.badge === "function"
@@ -833,28 +935,30 @@ var useTableRender = function (params) {
833
935
  ctx.fillRect(drawX, fixedY, actualWidth, rowHeight);
834
936
  // 处理序号列
835
937
  if (column.key === "__index__") {
836
- // 合计行序号列显示空
837
- if (rowType === "summary")
938
+ // 非合计行显示序号
939
+ if (rowType !== "summary") {
940
+ var indexText = String(rowIndex + 1);
941
+ ctx.fillStyle = COLORS.text;
942
+ ctx.font = "".concat(FONT_WEIGHT, " ").concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
943
+ ctx.textBaseline = "middle";
944
+ setTextAlign(ctx, "center");
945
+ var textX = drawX + actualWidth / 2;
946
+ var textY = fixedY + rowHeight / 2;
947
+ ctx.fillText(indexText, textX, textY);
838
948
  return;
839
- var indexText = String(rowIndex + 1);
840
- ctx.fillStyle = COLORS.text;
841
- ctx.font = "".concat(FONT_WEIGHT, " ").concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
842
- ctx.textBaseline = "middle";
843
- setTextAlign(ctx, "center");
844
- var textX = drawX + actualWidth / 2;
845
- var textY = fixedY + rowHeight / 2;
846
- ctx.fillText(indexText, textX, textY);
847
- return;
949
+ }
950
+ // 合计行序号列继续执行后面的逻辑,可能显示"合计"文字
848
951
  }
849
952
  // 处理选择框列
850
953
  if (column.key === "__selection__") {
851
- // 合计行选择框列显示空
852
- if (rowType === "summary")
954
+ // 非合计行显示选择框
955
+ if (rowType !== "summary") {
956
+ var checkboxX = drawX + actualWidth / 2;
957
+ var textY = fixedY + rowHeight / 2;
958
+ drawCheckbox(ctx, checkboxX, textY, isSelected, false, false);
853
959
  return;
854
- var checkboxX = drawX + actualWidth / 2;
855
- var textY = fixedY + rowHeight / 2;
856
- drawCheckbox(ctx, checkboxX, textY, isSelected, false, false);
857
- return;
960
+ }
961
+ // 合计行选择框列继续执行后面的逻辑,可能显示"合计"文字
858
962
  }
859
963
  // 获取单元格值
860
964
  var dataIndex = column.dataIndex || column.key;
@@ -36,6 +36,10 @@ interface ICanvasColumnType<RecordType = any> {
36
36
  * 对齐方式
37
37
  */
38
38
  align?: "left" | "center" | "right";
39
+ /**
40
+ * 表头对齐方式(如果不设置,使用全局 headerAlign 或 align)
41
+ */
42
+ headerAlign?: "left" | "center" | "right";
39
43
  /**
40
44
  * 是否固定列
41
45
  */
@@ -249,6 +253,10 @@ interface ICanvasTableProps<RecordType = any> {
249
253
  * 表头换行
250
254
  */
251
255
  headerWrap?: boolean;
256
+ /**
257
+ * 表头对齐方式(默认居中)
258
+ */
259
+ headerAlign?: "left" | "center" | "right";
252
260
  /**
253
261
  * 勾选配置
254
262
  */
@@ -394,6 +402,86 @@ interface ICanvasTableProps<RecordType = any> {
394
402
  * 表格id(用于自动高度计算时定位元素)
395
403
  */
396
404
  canvasTableId?: string;
405
+ /**
406
+ * 表格ref句柄,用于暴露表格的一些方法
407
+ */
408
+ tableRefHandle?: React__default.Ref<ICanvasTableRefHandle>;
409
+ /**
410
+ * 导出excel的一些配置
411
+ */
412
+ exportExcelConfig?: {
413
+ topDescription?: string;
414
+ time?: string;
415
+ topDescriptionRowHeight?: number;
416
+ fileName: string;
417
+ };
418
+ }
419
+ /**
420
+ * CanvasTable 暴露的方法
421
+ */
422
+ interface ICanvasTableRefHandle {
423
+ /**
424
+ * 获取当前表格的配置信息(动态列配置)
425
+ */
426
+ getDynamicList: () => any[];
427
+ /**
428
+ * 动态列配置重置
429
+ */
430
+ onResetDynamicList: () => void;
431
+ /**
432
+ * 动态列配置设置
433
+ */
434
+ onSetDynamicList: (list: any[]) => void;
435
+ /**
436
+ * 导出Excel
437
+ */
438
+ exportExcel?: (fileName: string, config?: {
439
+ topDescription?: string;
440
+ time?: string;
441
+ topDescriptionRowHeight?: number;
442
+ }) => void;
443
+ /**
444
+ * 获取表格容器
445
+ */
446
+ getContainer: () => HTMLDivElement | null;
447
+ /**
448
+ * 全屏展示表格
449
+ */
450
+ toggleFullScreen: () => void;
451
+ /**
452
+ * 获取选中的行keys
453
+ */
454
+ getSelectedRowKeys: () => React__default.Key[];
455
+ /**
456
+ * 设置选中的行keys
457
+ */
458
+ setSelectedRowKeys: (keys: React__default.Key[]) => void;
459
+ /**
460
+ * 滚动到指定位置
461
+ */
462
+ scrollTo: (params: {
463
+ x?: number;
464
+ y?: number;
465
+ }) => void;
466
+ /**
467
+ * 获取当前排序状态
468
+ */
469
+ getSortState: () => {
470
+ field: string | null;
471
+ order: SortOrder;
472
+ };
473
+ /**
474
+ * 获取当前过滤状态
475
+ */
476
+ getFilterState: () => Record<string, any[]>;
477
+ /**
478
+ * 清除排序
479
+ */
480
+ clearSort: () => void;
481
+ /**
482
+ * 清除过滤
483
+ */
484
+ clearFilter: () => void;
397
485
  }
398
486
 
399
- export { ColumnDataType, FilterConfig, IBadgeProps, ICanvasColumnType, ICanvasColumnsType, ICanvasRowSelection, ICanvasTableProps, SortOrder };
487
+ export { ColumnDataType, FilterConfig, IBadgeProps, ICanvasColumnType, ICanvasColumnsType, ICanvasRowSelection, ICanvasTableProps, ICanvasTableRefHandle, SortOrder };
@@ -24,13 +24,17 @@ var findColumnByKey = function (columns, key) {
24
24
  /**
25
25
  * 递归处理列的render函数(转换为统一的调用格式)
26
26
  */
27
- var processColumnRender = function (column, renderMode, headerWrap) {
27
+ var processColumnRender = function (column, renderMode, headerWrap, headerAlign) {
28
28
  if (renderMode === void 0) { renderMode = "object"; }
29
29
  var processedColumn = __assign({}, column);
30
30
  if (headerWrap) {
31
31
  processedColumn.wrap =
32
32
  processedColumn.wrap === undefined ? headerWrap : processedColumn.wrap;
33
33
  }
34
+ // 应用表头对齐方式(仅当列没有设置 headerAlign 或 align 时)
35
+ if (headerAlign && !processedColumn.headerAlign && !processedColumn.align) {
36
+ processedColumn.headerAlign = headerAlign;
37
+ }
34
38
  // 处理当前列的render函数
35
39
  if (column.render) {
36
40
  var render_1 = column.render;
@@ -44,7 +48,7 @@ var processColumnRender = function (column, renderMode, headerWrap) {
44
48
  // 递归处理children
45
49
  if (column.children && Array.isArray(column.children)) {
46
50
  processedColumn.children = column.children.map(function (child) {
47
- return processColumnRender(child, renderMode, headerWrap);
51
+ return processColumnRender(child, renderMode, headerWrap, headerAlign);
48
52
  });
49
53
  }
50
54
  return processedColumn;
@@ -38,6 +38,13 @@ var FONT_SIZE = 13;
38
38
  var FONT_WEIGHT = "400"; // 正常字重,避免过细导致不清晰
39
39
  // 图标尺寸
40
40
  var CHECKBOX_SIZE = 16;
41
- var SORT_ICON_SIZE = 6;
41
+ var SORT_ICON_SIZE = 6;
42
+ var SORT_ICON_WIDTH = 15; // 排序图标宽度(用于表头宽度计算)
43
+ var FILTER_ICON_WIDTH = 15; // 筛选图标宽度(用于表头宽度计算)
44
+ // 间距和内边距
45
+ var ICON_SPACING = 4; // 图标之间的间距
46
+ var TEXT_PADDING = 5; // 文本内边距
47
+ // 行高计算
48
+ var LINE_HEIGHT = FONT_SIZE + 5; // 字体大小 + 行间距5px
42
49
 
43
- export { CHECKBOX_SIZE, COLORS, DEFAULT_COLUMN_WIDTH, DEFAULT_SELECTION_COLUMN_WIDTH, FONT_FAMILY, FONT_SIZE, FONT_WEIGHT, MIN_SCROLLBAR_SIZE, SCROLLBAR_PADDING, SCROLLBAR_SIZE, SORT_ICON_SIZE };
50
+ export { CHECKBOX_SIZE, COLORS, DEFAULT_COLUMN_WIDTH, DEFAULT_SELECTION_COLUMN_WIDTH, FILTER_ICON_WIDTH, FONT_FAMILY, FONT_SIZE, FONT_WEIGHT, ICON_SPACING, LINE_HEIGHT, MIN_SCROLLBAR_SIZE, SCROLLBAR_PADDING, SCROLLBAR_SIZE, SORT_ICON_SIZE, SORT_ICON_WIDTH, TEXT_PADDING };
@@ -1,3 +1,5 @@
1
+ import { FONT_SIZE, FONT_FAMILY, TEXT_PADDING, LINE_HEIGHT, FILTER_ICON_WIDTH, SORT_ICON_WIDTH, ICON_SPACING } from './constants.js';
2
+
1
3
  /**
2
4
  * 多级表头工具函数
3
5
  */
@@ -96,13 +98,6 @@ function calculateLayerHeights(columns, baseHeaderHeight, columnRenderInfos) {
96
98
  }
97
99
  var flattenedHeaderRows = flattenHeaders(columns);
98
100
  var leafColumns = getLeafColumns(columns);
99
- var FONT_SIZE = 13;
100
- var FONT_FAMILY = '"Microsoft YaHei", 微软雅黑, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
101
- var LINE_HEIGHT = 20;
102
- var FILTER_ICON_WIDTH = 15;
103
- var SORT_ICON_WIDTH = 15;
104
- var ICON_SPACING = 4;
105
- var TEXT_PADDING = 5;
106
101
  // 创建临时canvas用于测量文本
107
102
  var tempCanvas = document.createElement("canvas");
108
103
  var ctx = tempCanvas.getContext("2d");
@@ -187,9 +182,10 @@ function calculateLayerHeights(columns, baseHeaderHeight, columnRenderInfos) {
187
182
  }
188
183
  maxLines = Math.max(maxLines, totalLines);
189
184
  });
190
- // 这一层的高度 = 基础高度 + (额外行数 * 行高)
185
+ // 当有换行时:上边距(5px) + 行数 * 行高 + 下边距(5px)
186
+ // 当没有换行时:使用原始的 baseHeaderHeight
191
187
  var layerHeight = maxLines > 1
192
- ? baseHeaderHeight + (maxLines - 1) * LINE_HEIGHT
188
+ ? 10 + maxLines * LINE_HEIGHT // 上下边距各5px,共10px
193
189
  : baseHeaderHeight;
194
190
  layerHeights.push(layerHeight);
195
191
  });
@@ -9,8 +9,9 @@ import { getLeafColumns } from './multiHeaderHelpers.js';
9
9
  * 注意:多级表头时,只处理叶子列(用于渲染数据)
10
10
  * @param columns 列配置
11
11
  * @param containerWidth 容器宽度(可选),如果提供且总宽度小于容器宽度,会自动填充
12
+ * @param manuallyResizedColumns 用户手动调整过宽度的列的key集合(可选),这些列不参与自动宽度分配
12
13
  */
13
- var calculateColumnRenderInfos = function (columns, containerWidth) {
14
+ var calculateColumnRenderInfos = function (columns, containerWidth, manuallyResizedColumns) {
14
15
  // 获取叶子列(多级表头时只有叶子列才渲染数据)
15
16
  var leafColumns = getLeafColumns(columns);
16
17
  // 第一次计算:使用原始宽度
@@ -27,13 +28,21 @@ var calculateColumnRenderInfos = function (columns, containerWidth) {
27
28
  totalWidth += columnWidth;
28
29
  });
29
30
  // 如果提供了容器宽度且总宽度小于容器宽度,将剩余宽度平分到各列
30
- // 注意:序号列和勾选框列除外,保持原宽度
31
+ // 注意:序号列、勾选框列、手动调整过的列除外,保持原宽度
31
32
  if (containerWidth && totalWidth < containerWidth) {
32
33
  var remainingWidth = containerWidth - totalWidth;
33
- // 统计需要平分宽度的列(排除序号列和勾选框列)
34
+ // 统计需要平分宽度的列(排除序号列、勾选框列和手动调整过的列)
34
35
  var columnsToExpand = tempInfos.filter(function (info) {
35
36
  var key = info.column.key;
36
- return key !== "__index__" && key !== "__selection__";
37
+ // 排除序号列和勾选框列
38
+ if (key === "__index__" || key === "__selection__") {
39
+ return false;
40
+ }
41
+ // 排除用户手动调整过宽度的列
42
+ if (manuallyResizedColumns && manuallyResizedColumns.has(key)) {
43
+ return false;
44
+ }
45
+ return true;
37
46
  });
38
47
  if (columnsToExpand.length > 0) {
39
48
  var additionalWidthPerColumn_1 = remainingWidth / columnsToExpand.length;
@@ -49,7 +49,7 @@ export { default as Sortable } from './es/sortable/sortable.js';
49
49
  export { default as ElectronSignatures } from './es/electronsignatures/index.js';
50
50
  export { default as message } from './es/message/index.js';
51
51
  export { default as CanvasTable } from './es/canvastable/canvasTable.js';
52
- export { ICanvasColumnType, ICanvasColumnsType, ICanvasTableProps } from './es/canvastable/interface.js';
52
+ export { ICanvasColumnType, ICanvasColumnsType, ICanvasTableProps, ICanvasTableRefHandle } from './es/canvastable/interface.js';
53
53
  export { Affix, Anchor, AutoComplete, Avatar, BackTop, Badge, Breadcrumb, Card, Carousel, Cascader, Checkbox, Col, Comment, ConfigProvider, Divider, Drawer, Dropdown, Empty, Grid, Image, Layout, List, Mentions, Menu, PageHeader, Popconfirm, Popover, Progress, Radio, Rate, Result, Row, Segmented, Skeleton, Slider, Space, Spin, Statistic, Steps, Switch, Timeline, Tooltip, Transfer, Typography, Upload, notification } from 'antd';
54
54
  export { IButtonProps } from './es/button/interface.js';
55
55
  export { IButtonDownloadProps } from './es/button/buttonDownload.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zmdms-webui",
3
- "version": "2.3.6",
3
+ "version": "2.3.7",
4
4
  "private": false,
5
5
  "main": "dist/index.es.js",
6
6
  "module": "dist/index.es.js",