前端使用xlsx.js实现 Excel 文件的导入与导出功能
在现代的 Web 开发中,处理文件上传和导出功能已经变得越来越常见,尤其是 Excel 文件的导入与导出。
我们将使用 Vue.js 和 XLSX.js 库来处理 Excel 文件的读取 和生成。XLSX.js 是一个强大的 JavaScript 库,可以在浏览器中解析和生成 Excel 文件。以下是如何一步步实现这个功能的示例。
项目需求
- 导入功能:允许用户上传 Excel 文件,并解析其内容。
- 导出功能:允许用户将数据导出为 Excel 文件。
环境准备
首先,确保你已经在 Vue 项目中安装了 XLSX.js
库,可以通过以下命令来安装:
npm install xlsx
代码实现
在下面的代码中,我们展示了如何在 Vue 组件中实现 Excel 文件的导入和导出。
<template>
<div class="maintenance">
<a-page-header style="border-bottom: 1px solid rgb(235, 237, 240)" :title="title">
<template slot="extra">
<a-button-group>
<a-button type="primary" icon="download" @click="handleExportExcelFile">导出excel</a-button>
</a-button-group>
<a-upload
accept=".xlsx,.xls"
:disabled="isUploadingExcel"
:before-upload="beforeUpload"
:custom-request="customRequest"
:showUploadList="false"
>
<a-button type="primary" :icon="isUploadingExcel ? 'loading' : 'plus'">导入excel</a-button>
</a-upload>
</template>
</a-page-header>
</div>
</template>
<script>
import * as XLSX from 'xlsx';
export default {
data() {
return {
title: 'Excel 文件处理',
isUploadingExcel: false,
pagination: {
current: 1
}
};
},
methods: {
// 初始化数据
async fetchData() {
this.isLoadingTableData = true;
// 在这里你可以从 API 或其他来源加载数据
this.isLoadingTableData = false;
},
// 搜索操作
async handleSearch() {
this.pagination.current = 1;
this.fetchData();
},
/** 图片预览=============== */
// 拦截上传操作,进行自定义处理
customRequest({ file, onSuccess, onError }) {
try {
// 调用文件处理方法
this.handleImportExcelFile(file);
// 如果没有错误,调用 onSuccess 回调
if (onSuccess) {
onSuccess();
}
} catch (error) {
// 如果发生错误,调用 onError 回调
if (onError) {
onError(error);
}
}
},
// 文件上传前的钩子函数
beforeUpload(file) {
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel';
if (!isExcel) {
this.$message.error('只能上传 Excel 文件!');
}
return isExcel;
},
// 处理导入的 Excel 文件
handleImportExcelFile(file) {
this.isUploadingExcel = true;
const reader = new FileReader();
reader.onload = e => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: 'binary' });
// 读取第一个工作表
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
// 将工作表转换为 JSON 数据
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
this.isUploadingExcel = false;
console.log(jsonData);
// 你可以在这里将 jsonData 保存到组件的 data 中
// this.excelData = jsonData;
};
reader.readAsBinaryString(file);
},
// 导出 Excel 文件
handleExportExcelFile() {
const data = [
['Name', 'Age'],
['Alice', 20],
['Bob', 25]
];
// 将数据转换为工作表
const ws = XLSX.utils.aoa_to_sheet(data);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
// 导出文件
XLSX.writeFile(wb, 'output.xlsx');
}
},
created() {},
async mounted() {
this.fetchData();
}
};
</script>
代码讲解
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:这是 Excel 2007 及以后版本(.xlsx 文件)的 MIME 类型,用于表示基于 Open XML 格式的电子表格。
application/vnd.ms-excel:这是 Excel 97-2003 版本(.xls 文件)的 MIME 类型,表示旧版 Excel 格式的电子表格。
1. 组件结构
在 Vue 模板中,我们使用了 a-page-header
和 a-button-group
来显示页面头部和操作按钮。主要操作按钮包括:
- 导出 Excel 按钮 :点击时触发
handleExportExcelFile
方法。 - 导入 Excel 按钮 :使用 Ant Design Vue 的
a-upload
组件来上传文件。
2. 导入 Excel 文件
- beforeUpload:在上传文件之前,我们先判断文件类型,确保它是 Excel 文件。如果不是,会显示错误消息。
- customRequest :这是上传自定义请求的钩子函数,它会在上传过程中调用
handleImportExcelFile
方法来处理文件。 - handleImportExcelFile :当文件上传完成后,我们使用
FileReader
读取文件内容,并利用XLSX.read
方法解析 Excel 文件。然后,我们将第一个工作表的数据转换成 JSON 格式,可以进一步处理或展示这些数据。
3. 导出 Excel 文件
- handleExportExcelFile :通过
XLSX.utils.aoa_to_sheet
方法,我们将一个二维数组转换成 Excel 工作表对象,接着用XLSX.writeFile
方法将其导出为output.xlsx
文件。
4. 上传与导出按钮的显示与隐藏
isUploadingExcel
变量用来控制上传按钮的加载状态,在文件上传过程中会显示一个加载动画,防止用户重复上传文件。
5. 分页与搜索功能
- 代码中提供了分页与搜索框架,虽然具体的分页和搜索实现未展示,但你可以根据自己的需求,进一步扩展数据请求与展示功能。
6.XLSX.utils.sheet_to_json()
方法
改方法是 xlsx
库用来将 Excel 工作表转换成 JSON 数据的函数。header
属性用来指定如何处理工作表的第一行(通常是列标题)以及如何映射到 JSON 对象的属性名。
header
属性的含义:
-
header: 1
:- 这表示将第一行数据作为数组的元素,而不是作为对象的键。
- 即,转换结果将是一个二维数组,每一行是一个数组。第一行会作为数据的首行,而不是作为字段名称。
- 适用于当你想直接操作原始数据时。
示例:
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); console.log(jsonData);
假设 Excel 中的工作表内容如下:
姓名 年龄 性别 张三 25 男 李四 30 女 输出的
jsonData
将是:[ ['姓名', '年龄', '性别'], ['张三', 25, '男'], ['李四', 30, '女'] ]
-
header: 'A'
(或者其他字符串值):- 当
header
设置为字符时,表示工作表的列头应该被视为从字母 "A" 开始。 - 这样,每一列会被命名为字符(例如
'A'
,'B'
,'C'
),并用于数据对象的属性名。
示例:
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 'A' }); console.log(jsonData);
对于相同的工作表数据,输出将是:
[ { A: '张三', B: 25, C: '男' }, { A: '李四', B: 30, C: '女' } ]
- 当
-
header: []
(数组形式):- 如果你传递一个数组作为
header
,那么这个数组将被用作 JSON 数据的字段名称。
示例:
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: ['姓名', '年龄', '性别'] }); console.log(jsonData);
输出将是:
[ { 姓名: '张三', 年龄: 25, 性别: '男' }, { 姓名: '李四', 年龄: 30, 性别: '女' } ]
- 如果你传递一个数组作为
-
header: true
:- 如果
header
设置为true
,则sheet_to_json
方法会自动使用工作表的第一行作为属性名。
示例:
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: true }); console.log(jsonData);
输出将是:
[ { 姓名: '张三', 年龄: 25, 性别: '男' }, { 姓名: '李四', 年龄: 30, 性别: '女' } ]
- 如果
这里,sheet_to_json()
会自动识别第一行(['姓名', '年龄', '性别']
)作为字段名,并将其应用到每一行的数据。