<input type="file" @change="fileChange">
1、txt文件
fileChange(event) {console.log('fileChange', event)const file = event.target.files[0];const reader = new FileReader();reader.readAsText(file);reader.onload = function(e) {console.log('reader', e)// 文本内容console.error(reader.result)// 切分行// reader.result.split('\n').forEach(function(v, i){// console.log(v);// });};
}
2、excel文件
1)安装解析插件xlsx
npm i xlsx
2)以 array 形式读取
import * as XLSX from 'xlsx'fileChange(event) {console.log('fileChange', event)const file = event.target.files[0];const reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = function(e) {console.log('reader', e)// excel文件 —— arrayconst data = new Uint8Array(e.target.result);const workbook = XLSX.read(data, {type: 'array'});// 假设我们只读取第一个工作表const firstSheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[firstSheetName];const jsonData = XLSX.utils.sheet_to_json(worksheet);console.log(jsonData, worksheet);};
}
3)以 binary 形式读取
import * as XLSX from 'xlsx'fileChange(event) {console.log('fileChange', event)const file = event.target.files[0];const reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = function(e) {console.log('reader', e)// excel文件 —— binaryconst workbook = XLSX.read(e.target.result, {type: 'binary'});const sheetNames = workbook.SheetNames; // 工作表名称集合const worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet// 输出字符串形式const csv = XLSX.utils.sheet_to_csv(worksheet);console.log(csv)// 输出数组形式const rows = csv.split('\n'); // 转化为数组rows.pop(); // 最后一行没用的console.log(rows); // 打印输出的数组};
}
3、vue案例
一个可以解析获取本地excel文件和txt文件的按钮组件,可以自定义插槽内容
<parseExcelBtn @getResult="getResult"></parseExcelBtn><parseExcelBtn @getResult="getResult" btnWidth="300px"><span>自定义按钮</span>
</parseExcelBtn>getResult(e) {console.log(e)
},
<template><div class="parse-excel-btn" :style="{width: btnWidth}" @click="doClick"><slot v-if="hasDefaultSlotContent"></slot><div v-else class="txt">{{ btnTxt }}</div><input type="file" hidden accept=".txt, .xlsx, .xls" ref="fileInput" @change="fileChange"></div>
</template><script lang="ts" setup>import { ref, withDefaults, defineProps, defineEmits, watch, useSlots, onMounted } from 'vue'import * as XLSX from 'xlsx' import { Message } from 'view-ui-plus'interface Props {btnTxt?: string, // 按钮文本btnWidth?: string // 按钮宽度resultType?: string // 输出结果类型readType?: string // 读取类型}const props = withDefaults(defineProps<Props>(), {btnTxt: '导入excel',btnWidth: 'auto',resultType: 'string', // array stringreadType: 'binary' // array binary})console.log(props)const emit = defineEmits(['getResult'])const fileInput = ref(null)const hasDefaultSlotContent = ref(false)const slots = useSlots();onMounted(() => {// 检查默认插槽是否有内容if (slots.default) {const slotContent = slots.default();if(slotContent) {hasDefaultSlotContent.value = true}// hasDefaultSlotContent.value = slotContent.some(({ vnode }) => {// console.log(vnode)// // 检查节点是否是文本节点且不为空// return vnode.type === Text && vnode.children.trim() !== '';// });}})// 按钮点击function doClick() {if(fileInput) {fileInput.value.click()}}// 本地文件选择function fileChange(event: any) {console.log('fileChange', event)const file = event.target.files[0];let testMsg = file.name.substring(file.name.lastIndexOf('.')+1)if(!['txt','xlsx', 'xls'].includes(testMsg)) {Message.error('不是excel文件~')return}const reader = new FileReader();if(testMsg === 'txt') {reader.readAsText(file);} else {if(props.readType === 'array'){reader.readAsArrayBuffer(file);} else {reader.readAsBinaryString(file);}}reader.onload = function(e) {// console.log('reader', e)if(testMsg === 'txt') {// txt文件// console.error(reader.result)// reader.result.split('\n').forEach(function(v, i){// console.log(v);// });emit('getResult', reader.result)} else {if(props.readType === 'array') {// excel文件 —— arrayconst data = new Uint8Array(e.target.result);const workbook = XLSX.read(data, {type: 'array'});// 假设我们只读取第一个工作表const firstSheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[firstSheetName];const jsonData = XLSX.utils.sheet_to_json(worksheet);// console.log(jsonData, worksheet);emit('getResult', jsonData)} else {// excel文件 —— binaryconst workbook = XLSX.read(e.target.result, {type: 'binary'});const sheetNames = workbook.SheetNames; // 工作表名称集合const worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheetconst csv = XLSX.utils.sheet_to_csv(worksheet);if(props.resultType === 'array') {// 数组形式const rows = csv.split('\n'); // 转化为数组rows.pop(); // 最后一行没用的// console.log(rows); // 打印输出的数组emit('getResult', rows)} else {// 字符串形式// console.log(csv)emit('getResult', csv)}}}}}
</script><style lang="scss" scoped>.parse-excel-btn {cursor: pointer;.txt {line-height:40px;background:#ebf2ff;border-radius:6px;text-align: center;font-weight:500;color:#0055ff;font-size:16px;}}</style>