自学内容网 自学内容网

vue上传Excel文件并直接点击文件列表进行预览

本文主要内容:用elementui的Upload 组件上传Excel文件,上传后的列表采用xlsx插件实现点击预览表格内容效果。

在项目中可能会有这样的需求,有很多种方法实现。但是不想要跳转外部地址,所以用了xlsx插件来解析表格,并展示表格内容。

1.安装或CDN引用xlsx插件

xlsx插件,通常指的是SheetJS/js-xlsx,是一个功能强大的JavaScript库,它允许开发者在浏览器或Node.js环境中读取、创建、编辑和导出Excel文件(包括.xls、.xlsx、.csv、.ods等多种格式)。这个库是由纯JavaScript编写的,不依赖于任何外部库,非常适合在前端应用中处理Excel数据,也适用于服务器端处理。

对于Vue开发者来说,vue-xlsx是一个专门为Vue框架设计的轻量级封装库,提供了Vue组件和更加Vue友好的API,它使得在Vue应用中处理Excel文件变得更加简单和直接。在这里我使用的是xlsx。

(1)在项目中安装xlsx

npm install vue-xlsx  //安装的是vue-xlsx库,基于SheetJS/js-xlsx的Vue封装库,专门为Vue框架设计
yarn add vue-xlsx
npm install xlsx  //安装的是SheetJS/js-xlsx库,纯JavaScript编写的库
yarn add xlsx 

(2)CDN引入xlsx

直接添加script标签引入

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

动态添加script标签引入

mounted() {
  // 引入xlsx插件
  const script = document.createElement("script");
  script.src = "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js";//使用.full.min.js引入成功,其他不行
  script.onload = () =>{
    console.log("xlsx脚本加载完成");
  }
  document.body.appendChild(script);
  this.assignmentQueryForm()
},

这里的资源是从免费的开源CDN服务网站上copy下来的,cdnjs网站地址:https://cdnjs.com/libraries/xlsx(需要不同版本的请前往)或开发文档概述 | SheetJS 中文网 (nodejs.cn)

(3)CDN引入xlsx没有起作用的解决方法

我这里引入了xlsx的CDN链接,但是运用xlsx还是报错。经过解决,发现使用xlsx.full.min.js这个后缀的文件可以,也不知道为什么。SheetJS开发文档说xlsx.full.min.js是完整的独立脚本。

2.导入xlsx

(1)安装的需要在Vue组件中导入vue-xlsx

import { XlSX } from 'vue-xlsx';
import { XlSX } from 'xlsx';

(2)CDN引入的xlsx直接使用

3.利用vue组件上传Excel文件

ref: 为上传组件设置了一个引用名。

action: 上传地址的URL,但这里设置为#,表明实际的上传逻辑将不会通过action属性指定的URL进行,而是通过:http-request属性自定义。

:on-preview: 点击已上传的文件链接时的回调。

:on-remove: 文件列表移除文件时的回调。

:file-list: 已经上传的文件列表,绑定到fileList数据属性。

:auto-upload: 是否在选取文件后立即进行上传,这里设置为false,表示需要手动触发上传。

:http-request: 覆盖默认的上传行为,可以自定义上传的实现。

:on-change: 文件状态改变时的回调。

multiple: 是否支持多文件上传。

因为只做了Excel文件解析,所以可以在upload组件中设置accept属性,限制只上传表格文件。

 accept=".xls, .xlsx"

代码如下:

<el-dialog title="批量导入" :visible.sync="dialogVisible1" width="30%">
  <el-form :model="importForm1" ref="removeControl" :rules="rules" label-position="right" label-width="auto"
    style="width: 50%">
    <el-form-item label="附件:" ref="myfile" style="background-color: #ffffff;">
      <div style="display: flex">
        <el-upload ref="upload" action="#" :on-preview="handleView" :on-remove="handleRemove" :file-list="fileList"
          :auto-upload="false" :http-request="uploadFile" :on-change="onChange" multiple>
          <el-button slot="trigger" size="small" type="primary" icon="el-icon-upload2"
            style="padding: 10px 20px">上传文件</el-button>
        </el-upload>
      </div>
    </el-form-item>
    <span @click="down()" style="cursor: pointer; color: blue">下载模板</span>
  </el-form>

  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible1 = false">取 消</el-button>
    <el-button type="primary" @click="goUpload()">确 定</el-button>
  </span>
</el-dialog>

4.解析并预览Excel文件

(1)文件上传成功后,点击解析文件

这里会用到upload组件的on-preview(点击已上传的文件链接时的回调)。

(2)解析Excel文件步骤

  • 使用new FileReader()创建一个文件存储,用于异步读取用户的文件内容。
  • 当文件读取操作成功完成时,触发onload事件。通过e.target.result获取到文件的内容。

  • 使用XLSX.read(data, { type: 'array' })将array格式的数据解析为Excel工作簿对象。

  • 通过tablelook.SheetNames[0]获取第一个工作表的名称,并通过tablelook.Sheets[firstSheetName]获取该工作表的数据。

  • 使用XLSX.utils.sheet_to_json(tablesheet, { header: 1 })将工作表的数据转换为JSON格式,其中{ header: 1 }表示第一行作为表头。

  • 使用FileReader接口的 readAsArrayBuffer() 方法用于开始读取指定Blob或File的内容。

(3)处理JSON数据(可根据自己需求)

  • 使用jsonData.shift()移除并保存表头(即第一行数据)
  • 通过filter方法过滤掉包含空值(nullundefined、空字符串'')的行
  • 使用map方法将数据中的每一行数据转换为一个对象,对象的键是表头,值是对应的数据。

我这里处理成了elementui的table格式数据,点击文件列表就可以直接展示表格解析的内容。

代码如下:

handleView(file) {
  const reader = new FileReader();
  reader.onload = (e) => {
    const data = e.target.result;
    const tablelook = XLSX.read(data, { type: 'array' });
    const firstSheetName = tablelook.SheetNames[0];
    const tablesheet = tablelook.Sheets[firstSheetName];
    const jsonData = XLSX.utils.sheet_to_json(tablesheet, { header: 1 });

    this.whiteListHeaders = jsonData.shift();
    // 过滤空数据  
    this.whiteListTable = jsonData.filter(row => {   
      return row.some(item => item !== null && item !== undefined && item !== '');  
    });  
    // 表格数据处理
    this.tableData2 = this.whiteListTable.map(row => {  
      const obj = {};  
      this.whiteListHeaders.forEach((header, cellIndex) => {  
        obj[header] = row[cellIndex];  
      });  
      return obj;  
    });  
    console.log("表格头", this.whiteListHeaders);  
    console.log("表格数据", this.whiteListTable);  
    console.log("this.tableData2", this.tableData2); 
  }
  reader.onerror = (error) => {  
    console.error('读取文件错误:', error);  
  };
  reader.readAsArrayBuffer(file.raw)
  this.dialogVisible2 = true;
},

预览文件表格展示

<el-dialog :visible.sync="dialogVisible2" title=" " width="50%">
  <el-table :data="tableData2" style="width: 100%" 
    :cell-style="{ 'text-align': 'center' }"
    :header-cell-style="{
    background: '#E5F2FF',
    color: '#000',
    'text-align': 'center',
    }">  
    <el-table-column  
      v-for="header in whiteListHeaders"  
      :key="header"  
      :prop="header"  
      :label="header"  
      width="140">  
    </el-table-column>  
  </el-table>  
</el-dialog>

注意:对于大型的Excel文件或需要进行复杂数据处理的场景,可能需要使用后端API来接收上传的Excel文件,在后端解析文件数据后返回给前端在展示,这样有利于提高性能。


原文地址:https://blog.csdn.net/qq_53911056/article/details/140500603

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!