JavaScript 读取本地 Excel 与 TXT 文件详解及 Vue 组件实现
作者:雾松时间:2026-10-31 14:12:52浏览:258
本文介绍在 JavaScript 中读取本地 TXT 和 Excel 文件的方法。通过 FileReader API 获取文本内容,利用 xlsx 库以 Array 或 Binary 模式解析 Excel 数据。同时提供基于 Vue 的封装组件示例,支持按钮插槽自定义与函数调用两种交互方式,帮助开发者快速实现文件上传与解析功能。
<input type="file" @change="fileChange">首先介绍如何读取 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);
// });
};
}接着讲解 Excel 文件的读取方式。
第一步需要安装 xlsx 解析插件。
npm i xlsx第二种方式是以 Array 数组形式读取 Excel 数据。
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文件 —— array
const 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);
};
}第三种方式是以 Binary 二进制形式读取 Excel 数据。
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文件 —— binary
const 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); // 打印输出的数组
};
}下面通过一个 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 string
readType: '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];
if(!file) {
return
}
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文件 —— array
const 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文件 —— binary
const 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);
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>第二种实现方式是采用函数调用的形式。
<button @click="handleParseExcel">excel</button>
mounted() {
this.doParseExcel = parseExcel({
// resultType?: string,
// readType?: string
}, this.parseExcelCallBack)
},
methods: {
// 回调
parseExcelCallBack(e) {
console.log(e)
},
// 导入
handleParseExcel() {
this.doParseExcel()
},
}import * as XLSX from 'xlsx'
import { Message } from 'view-ui-plus'
export function parseExcel(props, fn) {
console.log('init parseExcel function')
const inputDom = document.createElement('input')
inputDom.type = 'file'
inputDom.accept = '.txt, .xlsx, .xls'
inputDom.addEventListener('change', fileChange)
// 本地文件选择
function fileChange(event) {
console.log('fileChange', event, event.target, event.target.value)
const file = event.target.files[0];
if(!file) {
return
}
let testMsg = file.name.substring(file.name.lastIndexOf('.')+1)
if(!['txt','xlsx', 'xls'].includes(testMsg)) {
Message.error('不是excel文件~')
// event.target.value = ''
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);
// });
fn(reader.result)
} else {
if(props.readType === 'array') {
// excel文件 —— array
const 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);
fn(jsonData)
} else {
// excel文件 —— binary
const 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);
if(props.resultType === 'array') {
// 数组形式
const rows = csv.split('\n'); // 转化为数组
rows.pop(); // 最后一行没用的
// console.log(rows); // 打印输出的数组
fn(rows)
} else {
// 字符串形式
// console.log(csv)
fn(csv)
}
}
}
inputDom.value = ''
}
reader.onerror = function(e) {
Message.error(e)
console.log(e)
inputDom.value = ''
}
}
return () => {
if(inputDom) {
inputDom.click()
}
}
}最后进行总结。
至此,关于 JavaScript 读取本地 Excel 和 TXT 文件内容的介绍已完成,更多相关 JS 读取本地文件内容的内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
作者最新文章
Vue项目中怎么集成JS颜色选择器组件
2026-11-05 13:28:32
Nuxt 3 快速上手:项目初始化与目录结构详解
2026-11-03 19:16:51
怎么在 Vue 或 React 项目中正确集成 viewer.js
2026-11-02 09:17:48
Vue3+Vue-Router+Vite实现动态路由的完整流程与代码示例
2026-11-01 03:30:58
el-tree限制选中个数的实例
2026-11-01 03:09:07
