# 用途
提供一个 Excel 文件,将里面的内容转成 JSON 数据用以展示、编辑等各种操作
# 安装
npm install -save vue3-xlsx
or
yarn add vue3-xlsx
# 实现
utils.js
import * as XLSX from 'xlsx'; | |
/** | |
* 命令式触发系统文件选择器,并返回所选文件数据 | |
*/ | |
export async function selectFile({ accept = '.*', multiple = false }) { | |
return new Promise((resolve) => { | |
const id = 'liuxing-select-file'; | |
let el = document.querySelector(`#${id}`); | |
if (el) { | |
document.body.removeChild(el); | |
} | |
el = document.createElement('input'); | |
el.setAttribute('id', id); | |
el.setAttribute('type', 'file'); | |
el.setAttribute('accept', accept); | |
if (multiple) { | |
el.setAttribute('multiple', 'multiple'); | |
} | |
el.style.display = 'none'; | |
el.addEventListener('change', (event) => { | |
const { files } = (event.target); | |
if (files) { | |
resolve(multiple ? files : files[0]); | |
} else { | |
resolve(null); | |
} | |
}); | |
document.body.append(el); | |
el.click(); | |
}); | |
} | |
// 命令时选择并读取文件,返回 ArrayBuffer | |
export function selectFileAsArrayBuffer(options) { | |
return new Promise((resolve) => { | |
selectFile(options).then((files) => { | |
if (!files || files.length === 0) return resolve(null); | |
const fileReader = new FileReader(); | |
fileReader.addEventListener('load', async (e) => resolve(e.target?.result)); | |
fileReader.readAsArrayBuffer((options.multiple === true ? files[0] : files)); | |
}); | |
}); | |
} | |
/** | |
* 将 Excel 中指定 Sheet 转换为记录列表,配合 {@link selectFileAsArrayBuffer} 一起使用更佳 | |
*/ | |
export function excel2Records({data,sheetName,header,debug = false,}) | |
{ | |
const workbook = XLSX.read(new Uint8Array(data), { type: 'array' }); | |
debug && console.debug('workbook', workbook); | |
//sheetName 缺省时取第一个 sheet | |
if (!sheetName) { | |
if (workbook.SheetNames.length > 0) { | |
sheetName = workbook.SheetNames[0]; | |
} else { | |
throw new Error('Excel 没有 Sheet 可供导入'); | |
} | |
} | |
debug && console.debug('sheetName', sheetName); | |
const sheet = workbook.Sheets[sheetName]; | |
debug && console.debug('sheet', sheet); | |
const rows = XLSX.utils | |
sheet_to_json(sheet, { | |
// 将 excel 的列头按元素索引顺序映射 | |
header, | |
}) | |
// 过滤掉表头 | |
.filter((v, index) => index !== 0); | |
debug && console.log('rows', rows); | |
return rows; | |
} |
index.vue
<template> | |
<Button @click="handleImportExcel">导入文件</Button> | |
</template> | |
<script lang="ts" setup> | |
import { selectFileAsArrayBuffer, excel2Records } from '../utils'; | |
// 导入 | |
async function handleImportExcel() { | |
loading.value = true; | |
const arrayBuffer = await selectFileAsArrayBuffer({ accept: '.xlsx', multiple: false }); | |
if (!arrayBuffer) return; | |
tableData.value = excel2Records({ | |
data: arrayBuffer, | |
// 按顺序设置 excel 文件中的表头 | |
header: [ | |
'head1', | |
'head2', | |
'head3', | |
'head4', | |
], | |
}); | |
console.log(tableData.value);// 获得解析后的表格数据 | |
} | |
</script> |