useFileReader 
- Category: 
Composables - Relate: 
FileReader - Last Changed: yesterday
 
演示 
显示演示代码
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
用法 
该组合式函数是对 FileReader API 的封装,用于读取文件内容。只需传入一个 File 对象,即可获取到文件内容。当然,假如传入的是一个 Ref<File> 或是一个 Getter (()=>File), 读取的文件内容也会随传入值的变化而自动更新,提供一个响应式的 FileReader。
vue
<script setup lang="ts">
import { useFileReader } from "@qww0302/use-bitable"
import { ref } from "vue"
const file = ref<File>()
/**
 * data: 文件内容,由 `options.load` 将 BinaryString 转换得到
 * pending: 加载状态
 * name: 文件名
 */
const { data, pending, name } = useFileReader(file, {
  load: (data, resolve) => {
    // 将 `BinaryString` 转换为其他类型
  },
  onError: (e) => {
    // 处理错误
  },
  onProgress: (e) => {
    // 处理进度
  },
})
</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
类型声明 
显示类型声明
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, T | null | undefined>
  pending: import("vue").Ref<boolean, boolean>
  name: import("vue").Ref<string, 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