lin-xin / blog

林鑫的个人博客,用于总结平时工作和学习中的经验。

Home Page:https://lin-xin.gitee.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

vue项目中实现Excel文件的上传和下载

lin-xin opened this issue · comments

前言

在后台管理项目中,Excel文件的上传和下载是比较常见的需求,可用于批量导入和导出数据。虽然这只是一个平平无奇的需求,但是对于作为一名前端开发者来说,有2种实现方式,分别为复杂和简单。首先来说下复杂的实现方式。

上传

xlsx.js 是一个用来转换 BASE64 编码的 XLSX 文件数据为 JavaScript 对象,也支持 JavaScript 对象到 XLSX 数据的转换。前端使用 xlsx.js 来解析 Excel,把解析后的数据根据服务器需要的格式进行处理后上传给服务器,可以减少服务器的处理工作,在并发量大的时候,把数据处理放大前端,是有利于服务器性能的。先安装xlsx,yarn add xlsx

<el-upload
	action="#"
	:limit="1"
	accept=".xlsx, .xls"
	:show-file-list="false"
	:before-upload="beforeUpload"
	:http-request="handleUpload"
>
	<el-button type="success" plain>上传Excel</el-button>
</el-upload>
<el-link href="/template.xlsx" target="_blank">下载Excel模板</el-link>

我们期望用户能按照我们想要的格式上传文件,所以需要给用户一个模板可以参考,只需要把模板文件 template.xlsx 放到 /public 目录下即可。

<script setup lang="ts">
import { UploadProps } from 'element-plus';
import * as XLSX from 'xlsx';

const arr = ref<any>([]);
const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => {
	// 3.拿到了excel文件中的数据存到数组中
    arr.value = await analysisExcel(rawFile);
    return true;
};
const analysisExcel = (file: File) => {
    return new Promise(function (resolve, reject) {
        const reader = new FileReader();
        reader.onload = function (e: ProgressEvent<FileReader>) {
            const data = e.target && e.target.result;
			// 2.data为readAsBinaryString转成的值,所以type需要保持一致
			//返回的datajson为WordBook对象
            let datajson = XLSX.read(data, {
                type: 'binary',
            });

            const sheetName = datajson.SheetNames[0];
            const result = XLSX.utils.sheet_to_json(datajson.Sheets[sheetName]);
            resolve(result);
        };
		// 1.读取文件为二进制格式
        reader.readAsBinaryString(file);
    });
};

const handleUpload = async () => {
	//4. 把数组传给服务器
   await axios.post('/api/xxx', {data: arr.value})
};
</script>

根据以上几个步骤,便可以把excel文件的内容提取出来并上传。

下载

上面说到 xlsx.js 也支持把 JS 对象转成 XLSX 数据,依然是从服务器返回数据给前端,前端再生成 Excel 文件进行下载。

const downloadExcel = async () => {
    const res = await axios.post('/api/xxx');
	const list = res.data; // 这里数据需要怎么处理就处理
	const WorkSheet = XLSX.utils.aoa_to_sheet(list);
	const new_workbook = XLSX.utils.book_new();
	XLSX.utils.book_append_sheet(new_workbook, WorkSheet, '第一页');
	XLSX.writeFile(new_workbook, `下载.xlsx`);
};

总结

以上就是复杂的实现方式,把文件处理部分放在了前端实现。那么简单的实现方式便是把处理逻辑交给服务器,前端打开掘金沸点,继续当一个快乐的摸鱼人。上传时只需要把文件上传给服务器,下载时服务器返回一个excel文件的下载地址,简单几行代码便完成需求,继续在等服务器接口。

讲真的,像这种前后端都可实现的需求,我们就要站在团队的角度去看待了,不要为了自身减少工作量,把事情都推给另外一端。把自己当成团队的老大,甚至是公司老板,站在更高的角度,为公司的最大利益化去思考每一件事情,有了这样的思维,我们肯定能把事情做好,而且很快,老板又可以换房换车了。