-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
99 lines (83 loc) · 2.47 KB
/
Copy pathindex.js
File metadata and controls
99 lines (83 loc) · 2.47 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import React from 'react'
var ExcelClipboardMultiline = ({headers}) => {
const process = async (event) => {
const [header, rows, types] = await buildFromClipboard(event)
const result = mapToJson(header, rows)
}
const mapToJson = (header, rows) => {
return rows.reduce((acc, row) => {
return [
...acc,
header.reduce((acc2, headerItem, index) => {
return {
...acc2,
[headerItem]: row[index]
}
}, {})
]
}, [])
}
// Multiline columns cannot have explicit double quotes within \n or \t
// '__' especial character
const sanitize = (text) => {
return text
.replace(/\r/g, '')
.replace(/(?<=\t|^)"([^"]|\n|"[^\n\t]+")*"(?:\t|\n|)/gm, (match, capture) => {
return match.replace(/\n(?!$)/gm, "__")
})
.trim('\n')
}
const sanitizeColumn = (text) => {
return text.trim()
.replace(/^"([^\"]*)"$/m, '$1')
.replace(/__/gm, '\n')
.replace(/ +/gm, ' ')
}
const transformColumn = (text) => {
return text.charAt(0).toUpperCase() + text.slice(1)
}
const separateRows = (text) => {
return text.match(new RegExp(`(^(?:[^\t]*\t){${headers.length - 1}}[^\t]*$)`, 'gm'))
}
const buildFromClipboard = (event) => {
return new Promise((resolve, reject) => {
var items = event.clipboardData.items
var data
for (var i = 0; i < items.length; i++) {
if (items[i].type == 'text/plain') {
data = items[i]
break
}
}
if (!data) reject()
data.getAsString((text) => {
text = sanitize(text)
var rowsOfText = separateRows(text)
var header = []
var rows = []
rowsOfText.forEach((rowAsText) => {
var row = rowAsText.split('\t').map((colAsText) => transformColumn(sanitizeColumn(colAsText)))
// The first row containing data is assumed to be the header
if (header.length == 0) {
// Remove empty columns
while (row.length && !row[row.length - 1].trim()) row.pop()
if (row.length == 0) return
header = row
} else {
rows = [...rows, row.slice(0, header.length)]
}
})
resolve([header, rows])
})
})
}
return (
<input
onPaste={process}
headers={4}
placeholder="Import with ctrl + c ~> ctrl + v"
value=""
/>
)
}
export default ExcelClipboardMultiline