Vue2+Element实现Excel文件上传下载预览【超详细图解】

打印 上一主题 下一主题

主题 853|帖子 853|积分 2559

目次
一、需求配景
二、落地实现 
1.文件上传
图片示例 
HTML代码 
业务代码
2.文件下载
图片示例
方式一:代码
方式二:代码
3.文件预览
图片示例
方式一:代码
方式二:代码


一、需求配景

   在一个愉快的年后,需求司理提出必要完成对单个Excel文件的上传、下载、预览的功能,对于一个没写过下载和预览的后端来说,真的非常痛苦,颠末不停百度+积极看别人的博客,最终实现如下图所示
  二、落地实现 

1.文件上传

图片示例 



HTML代码 

  1. <template>
  2.     <el-upload v-model="form.upload" ref="upload" name="file" action="" drag :on-remove="handleRemove" :on-success="handleSuccess" multiple :limit="1" accept=".xls,.xlsx" :before-upload="beforeUpload" :http-request="handleRequest" :on-exceed="handleExceed">
  3.       <i class="el-icon-upload" style="color: #409eff"></i>
  4.       <div class="el-upload__tip"><span style="color: #333333;font-size: 13px">点击或将文件拖拽到这里上传</span>
  5.       </div>
  6.       <div class="el-upload__tip"><span style="color: #999999;font-size: 13px">仅支持单文件上传,文件上传行数最多1000,上传格式支持:.xls .xlsx</span>
  7.       </div>
  8.     </el-upload>
  9. <template>
复制代码
   参数解释
  name="file":是传到后端时,它接收这个文件的参数名叫file,本人没有仔细研究,因为在调接口时,可个性化定制参数名,后续贴的代码会提到。
  action="":这个Element官方文档写的是一个上传的固定链接,假的,用不了。通常在开辟中,也是自界说上传逻辑,以是这里置空。
  drag:启用拖拽上传,Element默认是false,直接写drag,不写:drag="true"就是true了。
  show-file-list:显示已上传文件列表,就是上传框下面的那行文件名,Element默认是false
  multiple:支持多选文件,通常与limit搭配使用。
  :limit="1":多选文件数量,如只必要单个文件就设置1。
  accept=".xls,.xlsx":担当上传的文件范例,我的需求是只要Excel的。
  n-remove="handleRemove":文件列表移除文件时的方法,就是文件列表右边那个小X触发时调用的。
  n-success="handleSuccess":文件上传成功时的方法,好比弹出一个上传成功提示。
  :before-upload="beforeUpload":上传文件之前的方法,通常用于上传文件前对文件的校验。
  :http-request="handleRequest":自界说上传方式的方法,好比远程调用。
  n-exceed="handleExceed":文件超出个数限定时的方法,好比弹出一个仅支持单个文件的提示。
  class="el-upload__tip":这个是Element封装好的样式,我的需求是必要笔墨在上传框里显示,以是都用el-upload__tip,官方文档另有个框外的用el-upload__text。
  
  业务代码

  1. export default {
  2.   name: "upload-dialog",
  3.   data() {
  4.     return {};
  5.   },
  6.   methods: {
  7.     handleSuccess(response, file, fileList) {
  8.       // 文件上传成功的回调
  9.       this.$message.success("上传成功");
  10.     },
  11.     handleRemove(file, fileList) {
  12.       console.log("删除", file, fileList);
  13.       // 看需要是否调用删除接口
  14.     },
  15.     beforeUpload(file) {
  16.       // 在这里进行个性化校验
  17.       const maxSize = 100 * 1024 * 1024; // 100MB(以字节为单位)
  18.       if (file.size > maxSize) {
  19.         // 这里可以添加你的提示逻辑(比如 Element UI 的 Message 警告)
  20.         this.$message.warning("文件大小不能超过 100 MB");
  21.         return false; // 阻止上传
  22.       }
  23.       return true;
  24.     },
  25.     handleRequest(option) {
  26.       // 自定义上传函数,用于并发上传
  27.       const formData = new FormData();
  28.       // 这个file就是后端的接收这个文件的参数名,如果为其他,则设成其他
  29.       formData.append("file", option.file);
  30.       // 如果还需要其他参数比如id,name,就在这里继续加
  31.       // formData.append("id", xxx);
  32.       // 发送请求,这个uploadApi是import进来的,自己写
  33.       uploadApi(formData).then(res => {
  34.         // 自定义上传方法的话,需要手动触发文件上传成功的钩子,不然文件状态会一直处于ready
  35.         option.onSuccess(null, option.file);
  36.       }).catch(error => {
  37.         // 自定义上传方法的话,需要手动触发文件上传失败的钩子,不然文件状态会一直处于ready
  38.         option.onError(error, option.file, null);
  39.       });
  40.     },
  41.     // 文件超出个数限制时的钩子
  42.     handleExceed(files, fileList) {
  43.       this.$message.warning("仅支持单个文件上传");
  44.     },
  45.   },
  46. };
复制代码
2.文件下载

图片示例


   我是通过<a></a>标签去实现文件下载的,假如想通过点击按钮实现,那么,在按钮内里套塞<a></a>即可
  方式一:代码

  1. <template>
  2.     <a :href="fileUrl" download>>文件</a>
  3. </template>
  4. export default {
  5.   data() {
  6.     return {
  7.       fileUlr: 'http://static.shanhuxueyuan.com/demo/excel.xlsx'
  8.     };
  9.   },
  10. }
复制代码
  这个href放是一个像http://static.shanhuxueyuan.com/demo/excel.xlsx如许的cdn文件地址,点击就可以直接下载到本地。
  假如必要通过二进制流、Blob对象实现的话,则自界说按钮,触发方法去调用。(详情请看方式二)
  方式二:代码

  1. <template>
  2.   <el-button type="text" @click="downloadFile(fileName)">
  3.     <span style="color: #0000FF">文件名</span>
  4.   </el-button>
  5. </template>
  6. export default {
  7.   data() {
  8.     return {};
  9.   },
  10.   methods: {
  11.     downloadFile(fileName) {
  12.         // 生成随机数据(示例:5行3列)
  13.         const data = [
  14.           ["Name", "Age", "Join Date"], // 表头
  15.           ...Array.from({length: 5}, (_, i) => [
  16.             `User ${i + 1}`, // 姓名
  17.             Math.floor(Math.random() * 30 + 20), // 随机年龄 (20-50)
  18.             new Date().toISOString().split("T")[0], // 当前日期
  19.           ]),
  20.         ];
  21.         // 创建工作表
  22.         const worksheet = XLSX.utils.aoa_to_sheet(data);
  23.         // 创建工作簿
  24.         const workbook = XLSX.utils.book_new();
  25.         XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
  26.         // 生成 Excel 文件
  27.         const excelBuffer = XLSX.write(workbook, {
  28.           bookType: "xlsx",
  29.           type: "array",
  30.         });
  31.         const blob = new Blob([excelBuffer], {
  32.           type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  33.         });
  34.         // 创建一个链接元素
  35.         const link = document.createElement('a');
  36.         link.href = URL.createObjectURL(blob);
  37.         link.download = fileName; // 设置下载的文件名
  38.         // 触发下载
  39.         link.click();
  40.         // 释放 URL 对象
  41.         URL.revokeObjectURL(link.href);
  42.         this.$message.success("文件下载成功");
  43.     },
  44.   }
  45. }
复制代码
3.文件预览

图片示例


   我的需求是:点击文件名,浏览器新打开一个标签页,展示文件内容。
  这个必要在route中额外添加一个路由映射
  1. {
  2.         path: '/preview',
  3.         name: 'preview',
  4.         meta: { title: '文件预览', requiresAuth: false },
  5.         component: () => import('@/views/preview.vue')
  6. },
复制代码
  还必要额外结合@vue-office/excel写页面 
  1. npm install @vue-office/excel vue-demi
复制代码
方式一:代码

入口代码
  1. <template>
  2.     <el-button type="text">
  3.         <a :href="'#/preview?fileUrl='+fileUrl" target="_blank">详情</a>
  4.     </el-button>
  5. </template>
  6. export default {
  7.   data() {
  8.     return {
  9.       fileUlr: 'http://static.shanhuxueyuan.com/demo/excel.xlsx'
  10.     };
  11.   },
  12. }
复制代码
 页面代码
  1. <template>
  2.   <vue-office-excel :src="excel" @rendered="rendered" @error="errorHandler"/>
  3. </template>
  4. <script>
  5. //引入VueOfficeExcel组件
  6. import VueOfficeExcel from "@vue-office/excel";
  7. //引入相关样式
  8. import "@vue-office/excel/lib/index.css";
  9. //引入解析Excel文件组件
  10. import XLSX from "xlsx";
  11. export default {
  12.   components: {
  13.     VueOfficeExcel,
  14.   },
  15.   data() {
  16.     return {
  17.       // 设置文档地址,支持三种格式
  18.       // string: Excel文件的网络地址,如cdn地址
  19.       // ArrayBuffer:以ArrayBuffer格式读取Excel文件的内容
  20.       // Blob:以Blob格式读取Excel文件的内容
  21.       excel: "",
  22.     };
  23.   },
  24.   mounted() {
  25.     this.getExcel();
  26.   },
  27.   methods: {
  28.     rendered() {
  29.       console.log("渲染完成");
  30.     },
  31.     errorHandler() {
  32.       console.log("渲染失败");
  33.     },
  34.     getExcel() {
  35.       this.excel = this.$route.query.fileUrl;
  36.     }
  37.   },
  38. };
  39. </script>
复制代码
  如许直接就是浏览器新打开一个标签页展示文件内容。与文件下载非常相似。
  假如必要使用二进制流、Blob对象打开的话。(详情请看方式二)
  方式二:代码

入口代码
  1. <template>
  2.     <el-button type="text">
  3.         <a :href="'#/preview'" target="_blank">详情</a>
  4.     </el-button>
  5. </template>
复制代码
页面代码
  1. <template>
  2.   <vue-office-excel :src="excel" @rendered="rendered" @error="errorHandler"/>
  3. </template>
  4. <script>
  5. //引入VueOfficeExcel组件
  6. import VueOfficeExcel from "@vue-office/excel";
  7. //引入相关样式
  8. import "@vue-office/excel/lib/index.css";
  9. //引入解析Excel文件组件
  10. import XLSX from "xlsx";
  11. export default {
  12.   components: {
  13.     VueOfficeExcel,
  14.   },
  15.   data() {
  16.     return {
  17.       // 设置文档地址,支持三种格式
  18.       // string: Excel文件的网络地址,如cdn地址
  19.       // ArrayBuffer:以ArrayBuffer格式读取Excel文件的内容
  20.       // Blob:以Blob格式读取Excel文件的内容
  21.       excel: "",
  22.     };
  23.   },
  24.   mounted() {
  25.     this.createRandomExcel();
  26.   },
  27.   methods: {
  28.     rendered() {
  29.       console.log("渲染完成");
  30.     },
  31.     errorHandler() {
  32.       console.log("渲染失败");
  33.     },
  34.     // 创建随机 Excel 文件
  35.     createRandomExcel() {
  36.       // 生成随机数据(示例:5行3列)
  37.       const data = [
  38.         ["Name", "Age", "Join Date"], // 表头
  39.         ...Array.from({length: 5}, (_, i) => [
  40.           `User ${i + 1}`, // 姓名
  41.           Math.floor(Math.random() * 30 + 20), // 随机年龄 (20-50)
  42.           new Date().toISOString().split("T")[0], // 当前日期
  43.         ]),
  44.       ];
  45.       // 创建工作表
  46.       const worksheet = XLSX.utils.aoa_to_sheet(data);
  47.       // 创建工作簿
  48.       const workbook = XLSX.utils.book_new();
  49.       XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
  50.       // 生成 Excel 文件
  51.       const excelBuffer = XLSX.write(workbook, {
  52.         bookType: "xlsx",
  53.         type: "array",
  54.       });
  55.       const blob = new Blob([excelBuffer], {
  56.         type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  57.       });
  58.       this.excel = blob;
  59.     },
  60.   },
  61. };
  62. </script>
复制代码
  上述代码,也适用于展示Word和PPT文件,修改对应的格式即可。 
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表