el-upload上传文件前端自己读取excel

1.读取方法 需要下载xlsx依赖

javascript 复制代码
export const readExcelFile = (file) => {
    return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsBinaryString(file.raw);
        reader.onload = (ev) => {
            try {
                let dataBinary = ev.target.result;
                let workBook = XLSX.read(dataBinary, { type: "binary", cellDates: true });
                let workSheet = workBook.Sheets[workBook.SheetNames[0]];
                const data = XLSX.utils.sheet_to_json(workSheet); //这里已经能拿到转换后的json
                resolve(data);
            } catch (err) {
                reject(err);
            }
        };
        reader.onerror = (ev) => {
            reject("文件读取失败");
        };
    });
};

2.使用

javascript 复制代码
<el-upload 
    action=""
    accept=".xls,.xlsx"
    ref="uploadVm"
    :auto-upload="false"
    :show-file-list="false"
    :limit="1"
    :on-exceed="handleExceed"
    :on-change="handleFileChange">
       <div class="btn fr_c fj_c cp" slot="reference">导入销售机会 /></div>     
</el-upload>
javascript 复制代码
        //文件超出覆盖
        handleExceed(files, fileList) {
            this.$set(fileList[0], "raw", files[0]); //raw就是指文件
            this.$set(fileList[0], "name", files[0].name); //name就是指文件名
            this.$refs.uploadVm.clearFiles(); //删除所有上传的文件
            this.$refs.uploadVm.handleStart(files[0]); //handleStart()指的是手动选择文件,Element Plus 的el-upload有说明
        },
        //change事件
        handleFileChange(file) {
            readExcelFile(file)
                .then((data) => {
                    let excelData = data.map((item) => {
                        return {
                            saleName: item["销售机会名称"],
                            customerName: item["客户名称"],
                        };
                    });
                })
                .catch((err) => {
                    this.$message.error("文件读取失败");
                    this.$refs.uploadVm.clearFiles();
                });
        },

如果后端配合可以通过前端传递formData对象 后端返回list那就不需要前端读取了

javascript 复制代码
//点击文件上传
const handleFileChange = debounce((file, fileArr) => {
    noDatauploadRef.value && noDatauploadRef.value.clearFiles();
    uploadRef.value && uploadRef.value.clearFiles();
    if (!checkFileSize(fileArr)) return;
    //整理form对象
    let formData = new FormData();
    fileArr.forEach((fileItem) => {
        formData.append("files", fileItem.raw);
    });
    formData.append("batchId", batchId.value);

    //整体校验接口 获取文件状态
    upLoadToHttp(formData).then((resList) => {
        if (!resList.length) {
            ElMessage.error("获取文件列表为空");
            return;
        }
        fileArr.forEach((item, index) => {
            state.fileList.push({
                ...resList[index],
                ...fileArr[index],
                fileType: item.name.slice(item.name.lastIndexOf(".")),
                fileName: item.name.slice(0, item.name.lastIndexOf(".")),
            });
        });
    });
}, 300);

// 多个文件时上传方法会调用多次 因为配置了手动上传 before-upload不生效
const checkFileSize = (fileArr) => {
    //文件数量限制
    if (fileArr.length > 10) {
        ElMessage.error("上传文件数量最多10个!");
        return false;
    }
    //文件大小限制
    let allfileSizeNum = fileArr
        .map((fileItem) => {
            return fileItem.size;
        })
        .reduce(function (prev, curr) {
            return prev + curr;
        }, 0);
    const is20M = allfileSizeNum / 1024 / 1024 < 20;
    if (!is20M) {
        ElMessage.error("上传文件总大小不能超过20MB!");
        return false;
    }
    return true;
};

限制文件类型可以在el-upload上的accept限制 但是上传时用户可以自己修改上传的文件类型为所有文件类型 所以拦截不住可以在change事件加一下拦截

javascript 复制代码
  //校验文件类型
            const fileName = file.name;
            const fileType = fileName.substring(fileName.lastIndexOf("."));
            if (fileType != ".xls" && fileType != ".xlsx") {
                this.$message.error("文件格式错误,请导入excel文件");
                return false;
            }
相关推荐
DigitalOcean42 分钟前
Laravel 开发者已在 DigitalOcean 上开通超过 10 万台服务器
前端·laravel
星始流年1 小时前
从 Tool 到 Skill——基于 LangChain 的服务端Skill实现
前端·langchain·agent
李惟1 小时前
开源本地通信库,纯客户端 RPC,像聊天一样通信
前端
YAwu111 小时前
深入解析 React 炫彩鼠标跟随标题组件:从坐标定位到动画性能
前端·react.js
GuWenyue1 小时前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
OpenTiny社区1 小时前
🎨 看完 GenUI SDK 源码我悟了!
前端·vue.js·github
叁两1 小时前
前端转型AI Agent该如何学习?(前置篇)
前端·人工智能·node.js
何时梦醒1 小时前
深入理解递归与快速排序 —— 从基础入门到手写实现
前端·javascript
爱勇宝1 小时前
淡泊名利之前,先承认我们都很焦虑
前端·后端·程序员
bonechips1 小时前
LLM 的无状态:从 HTTP 协议到对话上下文工程
前端·javascript