@@ -8,9 +8,11 @@ import 'handsontable/languages/zh-CN.js';
8
8
import 'handsontable/dist/handsontable.full.css' ;
9
9
import './style.scss' ;
10
10
11
+ type ICopyType = 'copyData' | 'copyHeaders' | 'copyHeadersAndData' ;
12
+
11
13
type IOptions = HotTableProps & {
12
- /** 是否展示复制值以及列名 */
13
- showCopyWithHeader ?: boolean ;
14
+ // 右键菜单中展示的选项 复制值/复制列名/复制列名和值 按钮 */
15
+ copyTypes ?: ICopyType [ ] ;
14
16
} ;
15
17
16
18
export interface ISpreadSheetProps {
@@ -33,10 +35,8 @@ const SpreadSheet: React.FC<ISpreadSheetProps> = forwardRef(
33
35
const tableRef = useRef < any > ( null ) ;
34
36
const copyUtils = new CopyUtils ( ) ;
35
37
const _timer = useRef < NodeJS . Timeout > ( ) ;
36
- const { showCopyWithHeader, ...restProps } = options || { } ;
37
- useImperativeHandle ( ref , ( ) => ( {
38
- tableRef,
39
- } ) ) ;
38
+ const { copyTypes = [ ] , ...restProps } = options || { } ;
39
+ useImperativeHandle ( ref , ( ) => tableRef . current ) ;
40
40
useEffect ( ( ) => {
41
41
if ( tableRef . current ) {
42
42
removeRenderClock ( ) ;
@@ -53,7 +53,7 @@ const SpreadSheet: React.FC<ISpreadSheetProps> = forwardRef(
53
53
clearTimeout ( _timer . current ) ;
54
54
} ;
55
55
56
- const getData = ( ) => {
56
+ const getShowData = ( ) => {
57
57
let showData = data ;
58
58
if ( ! showData ?. length ) {
59
59
const emptyArr = new Array ( columns . length ) . fill ( '' , 0 , columns . length ) ;
@@ -75,56 +75,101 @@ const SpreadSheet: React.FC<ISpreadSheetProps> = forwardRef(
75
75
}
76
76
} ;
77
77
78
- const beforeCopy = ( arr : any [ ] ) => {
79
- /**
80
- * 去除格式化
81
- */
78
+ /**
79
+ * 去除格式化
80
+ */
81
+ const beforeCopy = ( arr : Array < Array < any > > ) => {
82
82
const value = arr
83
83
. map ( ( row : any [ ] ) => {
84
84
return row . join ( '\t' ) ;
85
85
} )
86
86
. join ( '\n' ) ;
87
+
87
88
copyUtils . copy ( value ) ;
88
89
return false ;
89
90
} ;
90
91
91
92
const getContextMenu = ( ) => {
92
- const items : Record < string , { name : string ; callback : Function } > = {
93
- copy : {
94
- name : '复制' ,
95
- callback : function ( this : any , _key : any ) {
96
- const indexArr = this . getSelected ( ) ;
97
- // eslint-disable-next-line prefer-spread
98
- const copyDataArr = this . getData . apply ( this , indexArr [ 0 ] ) ;
99
- beforeCopy ( copyDataArr ) ;
100
- } ,
101
- } ,
93
+ // 获取值
94
+ const getCopyData = ( ) => {
95
+ // 调用的是 handsontable 的方法(在 handsontable.d.ts)
96
+ const selectedIndexArr = tableRef . current ?. hotInstance ?. getSelected ( ) ;
97
+ let dataArr : Array < any > = [ ] ;
98
+
99
+ if ( Array . isArray ( selectedIndexArr ) ) {
100
+ selectedIndexArr . forEach ( ( arr , index ) => {
101
+ const [ r , c , r2 , c2 ] = arr || [ ] ;
102
+ const colData : [ ] =
103
+ tableRef . current ?. hotInstance ?. getData ( r , c , r2 , c2 ) || [ ] ;
104
+ if ( index === 0 ) {
105
+ dataArr . push ( ...colData ) ;
106
+ } else {
107
+ dataArr = dataArr . map ( ( item : any [ ] , index : number ) => {
108
+ return item . concat ( colData [ index ] ) ;
109
+ } ) ;
110
+ }
111
+ } ) ;
112
+ }
113
+ return dataArr ;
102
114
} ;
103
- if ( showCopyWithHeader ) {
104
- const copyWithHeaderItem = {
105
- name : '复制值以及列名' ,
106
- callback : function ( this : any , _key : any , selection : any ) {
107
- const indexArr = this . getSelected ( ) ;
108
- // eslint-disable-next-line prefer-spread
109
- let copyDataArr = this . getData . apply ( this , indexArr [ 0 ] ) ;
110
- const columnStart = selection ?. [ 0 ] ?. start ?. col ;
111
- const columnEnd = selection ?. [ 0 ] ?. end ?. col ;
112
- let columnArr ;
115
+ // 获取列名
116
+ const getCopyHeaders = ( selection : Array < any > ) => {
117
+ let headerArr : Array < any > = [ ] ;
118
+ if ( Array . isArray ( selection ) ) {
119
+ selection . forEach ( ( it ) => {
120
+ const columnStart = it . start ?. col ;
121
+ const columnEnd = it . end ?. col ;
113
122
if ( columnStart !== undefined && columnEnd !== undefined ) {
114
- columnArr = columns . slice ( columnStart , columnEnd + 1 ) ;
115
- }
116
- if ( columnArr ) {
117
- copyDataArr = [ columnArr , ...copyDataArr ] ;
123
+ headerArr = headerArr . concat ( columns . slice ( columnStart , columnEnd + 1 ) ) ;
118
124
}
119
- beforeCopy ( copyDataArr ) ;
120
- } ,
121
- } ;
122
- // 目前版本不支持 copy_with_column_headers 暂时用 cut 代替,以达到与copy类似的表现
123
- items [ 'cut' ] = copyWithHeaderItem ;
125
+ } ) ;
126
+ }
127
+ return headerArr ;
128
+ } ;
129
+
130
+ const copyDataItem = {
131
+ name : '复制值' ,
132
+ callback : function ( _key : string ) {
133
+ const copyDataArr = getCopyData ( ) ;
134
+ beforeCopy ( copyDataArr ) ;
135
+ } ,
136
+ } ;
137
+ const copyHeadersItem = {
138
+ name : '复制列名' ,
139
+ callback : function ( _key : string , selection : Array < any > ) {
140
+ const copyHeaders = getCopyHeaders ( selection ) ;
141
+ beforeCopy ( [ copyHeaders ] ) ;
142
+ } ,
143
+ } ;
144
+ const copyHeadersAndDataItem = {
145
+ name : '复制列名和值' ,
146
+ callback : function ( _key : string , selection : Array < any > ) {
147
+ const copyDataArr = getCopyData ( ) ;
148
+ const copyHeaders = getCopyHeaders ( selection ) ;
149
+ beforeCopy ( [ copyHeaders , ...copyDataArr ] ) ;
150
+ } ,
151
+ } ;
152
+
153
+ // 目前 items 在 https://github.com/handsontable/handsontable/blob/6.2.2/handsontable.d.ts#L779,自定义方法也可以被执行
154
+ const items : Partial < Record < ICopyType , any > > = { } ;
155
+ if ( Array . isArray ( copyTypes ) && copyTypes ?. length ) {
156
+ // 复制值
157
+ if ( copyTypes . includes ( 'copyData' ) ) {
158
+ items [ 'copyData' ] = copyDataItem ;
159
+ }
160
+ // 复制列名
161
+ if ( copyTypes . includes ( 'copyHeaders' ) ) {
162
+ items [ 'copyHeaders' ] = copyHeadersItem ;
163
+ }
164
+ // 复制列名和值
165
+ if ( copyTypes . includes ( 'copyHeadersAndData' ) ) {
166
+ items [ 'copyHeadersAndData' ] = copyHeadersAndDataItem ;
167
+ }
168
+ } else {
169
+ items [ 'copyData' ] = copyDataItem ;
124
170
}
125
- return {
126
- items,
127
- } as any ;
171
+
172
+ return { items } as any ;
128
173
} ;
129
174
130
175
return (
@@ -143,7 +188,7 @@ const SpreadSheet: React.FC<ISpreadSheetProps> = forwardRef(
143
188
: columns ?. [ index as number ] ;
144
189
return `<span title="${ title } ">${ title } </span>` ;
145
190
} }
146
- data = { getData ( ) }
191
+ data = { getShowData ( ) }
147
192
mergeCells = { getMergeCells ( ) }
148
193
cell = { getCell ( ) }
149
194
readOnly
0 commit comments