├── .gitignore
├── .idea
├── modules.xml
├── vcs.xml
├── vue-datasheet.iml
└── workspace.xml
├── README.md
├── assets
└── example1.gif
├── index.js
├── lib
├── ComponentCell.vue
├── DataCell.vue
├── DataSheet.vue
├── constant.js
├── index.js
└── react-datasheet.css
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *~
3 | *.iml
4 | .*.haste_cache.*
5 | .DS_Store
6 | .idea
7 | npm-debug.log
8 | node_modules
9 | .nyc_output
10 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vue-datasheet.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | before
55 | beforeD
56 | beforeDestroy
57 | removeAllListeners
58 | pageClick
59 | created
60 | defaultState
61 | props
62 | es
63 | handleKey
64 | test
65 | _input
66 | input
67 | forceEdit
68 | forceedit
69 | selected
70 | editing
71 | onSelect
72 | console
73 | data
74 | onDoubleClick
75 | doub
76 | updated
77 | reverting
78 | change
79 | console.log
80 | wa
81 | wat
82 | watch
83 | onChange
84 |
85 |
86 |
87 |
88 |
89 |
90 |
106 |
107 |
108 |
109 |
110 | true
111 |
112 | false
113 | true
114 |
115 |
116 | true
117 | DEFINITION_ORDER
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 | project
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 | project
270 |
271 |
272 | true
273 |
274 |
275 |
276 | DIRECTORY
277 |
278 | false
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 | 1513875786860
289 |
290 |
291 | 1513875786860
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-datasheet
2 |
3 | 简单易用的在线excel插件
4 |
5 | npm install vue-datasheet --save
6 |
7 | 
8 | ## 选项
9 |
10 | 选项 | 类型 | 描述
11 | :--- | :---: | :---
12 | data | Array | 二维数组,每个元素的属性会传递给对应单元格
13 | valueRenderer | func | 渲染单元格的方法: `function(cell, i, j)`
14 | onChange | func | 发生变化的回调函数: `function(cell, i, j, newValue) {}`
15 | onPaste | func | 粘贴的回调函数: `function(array) {}`
16 | onContextMenu | func | 鼠标右键的上下文菜单回调: `function(event, cell, i, j)`
17 | parsePaste | func | `function (string) {}` 粘贴时对内容字符串处理的回调函数
18 |
19 | ## 单元格选项
20 |
21 | Option | Type | Default | Description
22 | :--- | :--- | :--- | :--
23 | readOnly | Bool | false | 是否只读
24 | key | String | undefined | 默认为行列的number
25 | className | Object | undefined | 单元格的class
26 | component | Function | undefined | component(h)形式的jsx自定义单元格
27 | forceComponent | bool | false | 默认只在edit时显示自定义单元格,为true则一直保持自定义单元格形式
28 | disableEvents | bool | false | cell会不可选取
29 | colSpan | number | 1 | cell的colSpan
30 | rowSpan | number | 1 | cell的rowSpan
31 | style | Object | undefined | cell的style
32 |
--------------------------------------------------------------------------------
/assets/example1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vyouyou/vue-datasheet/dbf855bf8c3891e598a710a23e73fae4c04ebd33/assets/example1.gif
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import DataSheet from "./lib/DataSheet.vue";
2 |
3 | module.exports = DataSheet;
4 |
--------------------------------------------------------------------------------
/lib/ComponentCell.vue:
--------------------------------------------------------------------------------
1 |
79 |
--------------------------------------------------------------------------------
/lib/DataCell.vue:
--------------------------------------------------------------------------------
1 |
121 |
--------------------------------------------------------------------------------
/lib/DataSheet.vue:
--------------------------------------------------------------------------------
1 |
414 |
415 |
418 |
419 |
421 |
--------------------------------------------------------------------------------
/lib/constant.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by vyouyou on 17-12-11.
3 | */
4 | export const TAB_KEY = 9;
5 | export const ENTER_KEY = 13;
6 | export const ESCAPE_KEY = 27;
7 | export const LEFT_KEY = 37;
8 | export const UP_KEY = 38;
9 | export const RIGHT_KEY = 39;
10 | export const DOWN_KEY = 40;
11 | export const DELETE_KEY = 46;
12 | export const BACKSPACE_KEY = 8;
13 | export const isEmpty = (obj) => Object.keys(obj).length === 0;
14 | export const range = (start, end) => {
15 | const array = [];
16 | const inc = (end - start > 0);
17 | for (let i = start; inc ? (i <= end) : (i >= end); inc ? i++ : i--) {
18 | inc ? array.push(i) : array.unshift(i);
19 | }
20 | return array;
21 | };
22 |
23 | export const nullFtn = (obj) => {};
24 |
25 | export const defaultParsePaste = (str) => {
26 | return str.split(/\r\n|\n|\r/)
27 | .map((row) => row.split("\t"));
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | import DataSheet from "./DataSheet.vue";
2 |
3 | export default DataSheet;
4 |
--------------------------------------------------------------------------------
/lib/react-datasheet.css:
--------------------------------------------------------------------------------
1 |
2 | table.data-grid {
3 | table-layout: fixed;
4 | border-collapse: collapse;
5 |
6 | }
7 |
8 | table.data-grid td.cell.updated {
9 | background-color: rgba(0, 145, 253, 0.16);
10 | transition: background-color 0ms ease;
11 | }
12 |
13 | table.data-grid td.cell {
14 | height: 24px;
15 | line-height: 23px;
16 | user-select: none;
17 | -moz-user-select: none;
18 | -webkit-user-select: none;
19 | -ms-user-select: none;
20 | cursor: cell;
21 | background-color: unset;
22 | transition: background-color 500ms ease;
23 | vertical-align: middle;
24 | text-align: right;
25 | border: 1px solid #DDD;
26 | padding: 0px 3px;
27 | }
28 |
29 | table.data-grid td.cell.selected {
30 | border: 1px double #0099CC;
31 | transition: none;
32 | }
33 |
34 | table.data-grid td.cell span {
35 | }
36 |
37 | table.data-grid td.cell div{
38 | width: 100%;
39 | line-height: 100%;
40 | height: 100%;
41 | }
42 |
43 | table.data-grid td.cell.selected div {
44 | position: absolute;
45 | left: 0px;
46 | top: 0px;
47 | width: 100%;
48 | line-height: 100%;
49 | height: 100%;
50 | box-shadow: 0 0 5px 3px rgba(0, 0, 0, 0.12);
51 | z-index: 2;
52 | }
53 |
54 | table.data-grid td.cell.selected div input {
55 | width: calc(100% - 6px);
56 | height: calc(100% - 6px);
57 | margin: 3px 3px;
58 | }
59 |
60 | /*table.data-grid td.cell.selected {*/
61 | /*box-shadow: inset 0 -100px 0 rgba(33, 133, 208, 0.15);*/
62 | /*}*/
63 |
64 | table.data-grid td.cell.read-only {
65 | background: whitesmoke;
66 | color: #666666;
67 | text-align: center;
68 | padding: 0px 0px;
69 | }
70 |
71 | table.data-grid td.cell > div.text {
72 | padding: 2px 5px;
73 | text-overflow: ellipsis;
74 | overflow: hidden;
75 | }
76 |
77 | table.data-grid td.cell div input {
78 | box-sizing: content-box;
79 | outline: none !important;
80 | border: 0px solid #0099CC;
81 | text-align: right;
82 | width: calc(100% - 1px);
83 | height: 100%;
84 | background: #ffffff;
85 | }
86 |
87 | table.data-grid td.cell {
88 | vertical-align: bottom;
89 | }
90 |
91 | table.data-grid td.cell,
92 | table.data-grid.wrap td.cell,
93 | table.data-grid.wrap td.cell.wrap,
94 | table.data-grid td.cell.wrap,
95 | table.data-grid.nowrap td.cell.wrap,
96 | table.data-grid.clip td.cell.wrap {
97 | white-space: normal;
98 | }
99 |
100 | table.data-grid.nowrap td.cell,
101 | table.data-grid.nowrap td.cell.nowrap,
102 | table.data-grid td.cell.nowrap,
103 | table.data-grid.wrap td.cell.nowrap,
104 | table.data-grid.clip td.cell.nowrap {
105 | white-space: nowrap;
106 | overflow-x: visible;
107 | }
108 |
109 | table.data-grid.clip td.cell,
110 | table.data-grid.clip td.cell.clip,
111 | table.data-grid td.cell.clip,
112 | table.data-grid.wrap td.cell.clip,
113 | table.data-grid.nowrap td.cell.clip {
114 | white-space: nowrap;
115 | overflow-x: hidden;
116 | }
117 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-datasheet",
3 | "version": "1.0.0",
4 | "description": "the best excel component for vue.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "vyouyou",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | vue-datasheet@^1.0.0:
6 | version "1.0.0"
7 | resolved "http://registry.npm.taobao.org/vue-datasheet/download/vue-datasheet-1.0.0.tgz#e718f73166b8b79e836fcdd4d7bf2fc49cf05155"
8 |
--------------------------------------------------------------------------------