useFileReader
- Category:
Composables
- Relate:
FileReader
- Last Changed: 2 weeks ago
Demo
Show demo code
vue
<script setup lang="ts">
import { useFileReader } from "@qww0302/use-bitable"
import { ref } from "vue"
import XLSX from "xlsx"
import { markdownTable } from "markdown-table"
const fileInput = ref<HTMLInputElement | null>(null)
const progress = ref(0)
const file = ref<File | null>(null)
const { name, pending, data } = useFileReader<Array<Array<string>>>(file, {
onProgress: (e: ProgressEvent<FileReader>) => {
progress.value = e.loaded / e.total
},
load(data, resolve) {
const wb = XLSX.read(data, { type: "buffer" })
const table = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {
header: 1,
}) as Array<Array<string>>
console.log(table)
resolve(table)
},
shallow: true,
})
const handleChange = (e: Event) => {
if ((e.target as HTMLInputElement).files!.length === 0) {
progress.value = 0
return
}
file.value = (e.target as HTMLInputElement).files![0]
}
const clear = () => {
file.value = null
fileInput.value!.value = ""
progress.value = 0
}
</script>
<template>
Choose a xls/xlsx file:
<input
ref="fileInput"
accept=".xls,.xlsx"
type="file"
@change="handleChange"
>
<ul>
<li>Name: {{ name }}</li>
<li>Pending: {{ pending }}</li>
<li>Progress: {{ progress }}</li>
</ul>
Data:
<div style="overflow: auto; max-height: 200px">
<pre><code>{{ JSON.stringify(data, null, 2) }}</code></pre>
</div>
Table:
<div style="overflow: auto; max-height: 200px">
<pre><code>{{ markdownTable(data ?? []) ?? "No Data" }}</code></pre>
</div>
<button @click="clear">
Clear
</button>
</template>
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
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
Usage
This composable function is a wrapper of FileReader
API, used to read the content of a file. Just pass in a File
object, and you can get the content of the file. Of course, if the passed-in value is a Ref<File>
or a Getter (()=>File
), the read file content will also be automatically updated with the change of the passed-in value, providing a responsive FileReader
.
vue
<script setup lang="ts">
import { useFileReader } from "@qww0302/use-bitable"
import { ref } from "vue"
const file = ref<File>()
/**
* data: file content, transformed from BinaryString by `options.load`
* pending: loading status
* name: file name
*/
const { data, pending, name } = useFileReader(file, {
load: (data, resolve) => {
// transform `BinaryString` to other type
},
onError: (e) => {
// handle error
},
onProgress: (e) => {
// handle progress
},
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Type Declarations
Show Type Declarations
ts
import { MaybeRefOrGetter } from "vue"
/**
* FileReader options
*/
export interface fileReaderOptions<T> {
/**
* Progress event handler
*
* 进度事件处理程序
*
* @param ev
* @returns
*/
onProgress?: (ev: ProgressEvent<FileReader>) => void
/**
* Error event handler
*
* 错误事件处理程序
*
* @param ev
* @returns
*/
onError?: (ev: ProgressEvent<FileReader>) => void
/**
* Load event handler
*
* 加载事件处理程序
*
* @param data
* @param resolve
* @returns
*/
load?: (data: ArrayBuffer, resolve: (value: T) => void) => void
/**
* Is data a shallowRef
*
* data 是否为 shallowRef
*/
shallow?: boolean
}
/**
* Use `FileReader`
*
* 使用 `FileReader` API
*
* @see https://use-bitable.vercel.app/zh/references/composables/useFileReader/
* @relation https://developer.mozilla.org/en-US/docs/Web/API/FileReader
* @param file
* @param options
* @returns
*/
export declare function useFileReader<T = string>(
file: MaybeRefOrGetter<File | null>,
options?: fileReaderOptions<T>,
): {
data: import("vue").Ref<T | null | undefined>
pending: import("vue").Ref<boolean>
name: import("vue").Ref<string>
}
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
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