当前位置: 首页 > news >正文

excel不经过后台实现解析和预览(vue)

数据流读取和数据解析方面通过xlsx组件

安装命令   npm install xlsx -S

它先将上传的excel变成流,然后再根据流进行下一步处理。这个流可以交给其他组件处理比如我用的预览组件是用了其他组件(@vue-office/excel)就是把这个流交给其它组件就实现预览了,

@vue-office/exce 预览组件 地址如下 

#docx文档预览组件
npm install @vue-office/docx vue-demi@0.14.6#excel文档预览组件
npm install @vue-office/excel vue-demi@0.14.6#pdf文档预览组件
npm install @vue-office/pdf vue-demi@0.14.6

如果是vue2.6版本或以下还需要额外安装 @vue/composition-api

npm install @vue/composition-api

<el-upload                class="upload-demo"                ref="upload"                action=""                :auto-upload="false"                :file-list="fileList"                :on-change="handleChange"                multiple                :show-file-list="false"                
>              <el-button type="text">点击上传{{ bankDialogIsShow }}</el-button>                         
</el-upload>
// 上一个html 上传后调用这个,这个方法处理后会调用弹窗,把必要的参数传到弹窗页面去处理显示操作等内容		
handleChange(file,fileList){        this.fileList = [fileList[fileList.length - 1]]; // 只能上传一个Excel,重复上传会覆盖之前的        this.file = file.raw;        let reader = new FileReader()        let _this = this        reader.readAsArrayBuffer(this.file)        const that = thisreader.onload = function () {      that.bankDialogIsShow = true     let buffer = reader.result            let bytes = new Uint8Array(buffer)            let length = bytes.byteLength            let binary = ''            for (let i = 0; i < length; i++) {                binary += String.fromCharCode(bytes[i])            }            let XLSX = require('xlsx')            let wb = XLSX.read(binary, {                type: 'binary'            })that.$refs.bankDialog.open(XLSX,wb,buffer)//这个里面的this,不是当前dom,上面有函数}},
<template><div><el-dialog title="提示" :visible.sync="dialogVisible" :fullscreen="true" :before-close="handleClose"><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="submist">确 定</el-button></span>excel预览部分<div style="width: 100vw; height: 600px;"><vue-office-pdf:key="componentKey"v-if="officeV":options="options":src="pdfUrl"@rendered="renderedHandler"@error="errorHandler"/></div>操作部分<el-tabs type="border-card" v-model="activeName" v-if="isTableShow" @tab-click="handleClick"> <el-tab-pane :label="name" v-for=" (name, key, index) in SheetNames" :key="key"><el-table style="width: 92vw;height: 200px; " :data="excelDataAllObj[name]" stripe><el-table-column label="序号" width="50" align="center"><template slot-scope="scope"><template v-if="scope.$index == 0"></template><template v-else>{{ scope.row['id'] }}</template></template></el-table-column><el-table-column label="帐号" width="150" align="center"><template slot-scope="scope"><template v-if="scope.$index == 0"><el-select v-model="selColumn[name]['帐号']" placeholder="请选择"><el-option v-for="item in optionsObj[name]" :key="item.value" :label="optionsObj[name][item]":value="optionsObj[name][item]"></el-option></el-select></template><template v-else>{{ scope.row[selColumn[name]['帐号']] }}</template></template></el-table-column>。。。。其他字段</el-table></el-tab-pane></el-tabs></el-dialog></div>
</template><script>
import { excelBankData } from "@/api/tab-bank";
import matchMap from "@/assets/matchMap.json"
import VueOfficePdf from "@vue-office/excel";
import '@vue-office/excel/lib/index.css'
import {Message
} from "element-ui";
export default {props: {// dialogVisible: {// 	type: Boolean,// 	default: false// }, //是否显示id: {type: String,default: ''}, //传递的id},data() {return {componentKey:0,// 预览组件的配置对象,设置xls: true才能预览展示xls类型,否则显示空白options:{xls: true,
//过滤器1beforeTransformData: (workbookData) => {console.log('beforeTransformData ',workbookData)return workbookData}, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
//过滤器2,我使用了这个 作用是只展示下面修改部分tab选择那个sheet,正常预览是导入有几个sheet就展示几个,这里有个问题是 arr.push(workbookData[this.activeName]) 改变赋值后 预览页面是不刷新的 需要handleClick(tab, event) {this.componentKey += 1;  }变换预览组件:ref,让它以为是新东西强制更新ui                
transformData: (workbookData) => {console.log('transformData ',workbookData)const arr = []arr.push(workbookData[this.activeName])return arr},},officeV:true,pdfUrl:'',matchMap:matchMap,testA: '',activeName: 0,isTableShow: false,dialogVisible: false,outTableData: [{}],outRelExcelMap: {},selColumn: {},outCnEnRel: {'帐号': 'account'},excelDataAll: [],excelDataAllObj: {},optionsObj: {},SheetNames: [],excelDatas: [],htmlExcel:''}},computed: {excelData() {}},methods: {handleClick(tab, event) {console.log(tab, event);// this.officeV = false// this.$nextTick(function(){//   this.officeV = true// })this.componentKey += 1;},findKeyByValue(obj, value) {const result = Object.entries(obj).find(([key, val]) => val === value);return result ? result[0] : null;},
//用于联想提示自动选择下拉框的findMatchKeyInJSON(excelColName){for(let subKey in matchMap){//   console.log(subKey,' matchMap ')if (matchMap.hasOwnProperty(subKey)) {const oneJSON = matchMap[subKey]const matchKey = oneJSON.find(e=> e==excelColName )if(matchKey){return subKey}}}return undefined},async submist() {//SheetNames//excelDataAllObjconst tdata = this.excelDataAllObjconst outCnEnRelTemp = this.outCnEnRellet outData = []for (let j = 0; j < this.SheetNames.length; j++) {const name = this.SheetNames[j]for (let i = 0; i < tdata[name].length; i++) {const excelOne = tdata[name][i]let outOne = {}for (let key in excelOne) {if (excelOne.hasOwnProperty(key)) {const outKeyCN = this.findKeyByValue(this.selColumn[name], key)if (outKeyCN) {const enKey = outCnEnRelTemp[outKeyCN]outOne[enKey] = excelOne[key]}}}outData.push(outOne)}}const respose = await excelBankData(outData)const { code, msg, data } = resposeMessage({message: data,type: msg,})},close() {this.optionsObj = {}this.excelDataAll = {}},getTableVal(keyName) {const t = scope.row[selColumn[keyName]]if (t) {return '笑话'}return "?"},handleClose(done) {this.$confirm('确认关闭?').then(_ => {done();}).catch(_ => { });},open(XLSX, wb,buffer) {this.pdfUrl =  buffer//  console.log('弹窗参数 ' + JSON.stringify(wb))this.dialogVisible = truethis.SheetNames = wb.SheetNamesthis.excelDatas = wb.Sheetsfor (let i = 0; i < wb.SheetNames.length; i++) {const sheetName = wb.SheetNames[i]this.$set(this.selColumn, sheetName, {})this.$set(this.optionsObj, sheetName, {})let excelData = {}excelData = XLSX.utils.sheet_to_json(wb.Sheets[sheetName])this.htmlExcel = XLSX.utils.sheet_to_json(wb.Sheets[sheetName])//  console.log('数据 '+i,wb.SheetNames[i],JSON.stringify(excelData))let outData = []let selOptions = []for (let i = 0; i < excelData.length; i++) {const obj = excelData[i]obj['id'] = i + ''let recordOne = {}outData.push(recordOne)let selOption = {}for (let key in obj) {if (obj.hasOwnProperty(key)) {//  console.log(key, obj[key]);if (key) {const wantColName = this.findMatchKeyInJSON(key)if(wantColName){this.$set(this.selColumn[sheetName], wantColName, key)}//  console.log('wantColName ',wantColName,' key ',key)this.optionsObj[sheetName][key] = key}}}//    // this.excelDataAll = [...excelData]// 固化i变量,防止地址内容变动影响对象键值对对应关系 huangjingnan 240825this.excelDataAllObj[sheetName] = excelData//    console.log(sheetName,' 弹窗中展示 excel上传数据 ', JSON.stringify(this.excelDataAllObj))}}this.isTableShow = true},renderedHandler() {console.log("渲染完成");},errorHandler() {console.log("渲染失败");}},components: {VueOfficePdf,}
};
</script>
<style scoped lang="scss">
/* 自定义滚动条样式 */
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar {width: 10px;/* 设置滚动条的宽度 */height: 100px;/* 设置滚动条的高度 */
}/* 自定义滚动条滑块样式 */
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-thumb {border-radius: 5px;/* 设置滑块的圆角 */background-color: rgba(144, 147, 153, 0.3);/* 设置滑块的背景颜色 */
}/* 自定义滚动条轨道样式 */
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-track {background-color: #f0f2f5;/* 设置轨道的背景颜色 */
}:deep .x-spreadsheet-bottombar{display: none;
}
</style>

相关文章:

excel不经过后台实现解析和预览(vue)

数据流读取和数据解析方面通过xlsx组件 安装命令 npm install xlsx -S 它先将上传的excel变成流&#xff0c;然后再根据流进行下一步处理。这个流可以交给其他组件处理比如我用的预览组件是用了其他组件&#xff08;vue-office/excel&#xff09;就是把这个流交给其它组件就…...

html5 + css3(上)

目录 HTML认知web标准vscode的简介和使用注释标题和段落换行和水平线标签文本格式化标签图片图片-基本使用图片-属性 绝对路径相对路径音频标签视频标签超链接 HTML基础列表列表-无序和有序列表-自定义 表格表格-使用表格-表格标题和表头单元格表格-结构标签&#xff08;了解&a…...

Flask+微信小程序实现Login+Profile

Python代码 首先flask的session用不了&#xff0c;只能用全局变量来实现。 import pymysql from flask import Flask, request, jsonify, session from flask_cors import CORS from flask import make_responseapp Flask(__name__) CORS(app, supports_credentialsTrue) #…...

后缀表达式中缀表达式转后缀表达式

后缀表达式的计算机求值 计算规则 从左至右扫描表达式&#xff0c;遇到数字时&#xff0c;将数字压入堆栈&#xff0c;遇到运算符时&#xff0c;弹出栈顶的两个数&#xff0c;用运算符对它们做相应的计算&#xff08;次顶元素 和 栈顶元素&#xff09;&#xff0c;并将结果入…...

Qemu开发ARM篇-7、uboot以及系统网络连接及配置

文章目录 1、uboot及linux版本网络设置1、宿主机虚拟网卡创建2、uboot使用tap0网卡3、启动测试 2、访问外网设置 在上一篇Qemu开发ARM篇-6、emmc/SD卡AB分区镜像制作并通过uboot进行挂载启动中&#xff0c;我们制作了AB分区系统镜像&#xff0c;并成功通过uboot加载kernel以及d…...

两数相加leetcode

第一个是测试用例代码&#xff0c;测试的是两个带头的逆序链表相加&#xff0c;并且有反转操作 但是题目要求的是不带头链表直接相加&#xff0c;不需要逆转&#xff0c;输出结果也是逆序的&#xff0c; 题解放在第二个代码中 #include<stdio.h> #include<stdlib.h…...

C0004.Qt中QComboBox设置下拉列表样式后,下拉列表样式无效的解决办法

问题描述 我们平时在使用Qt Creator对控件QComboBox的样式进行设置后&#xff0c;在运行程序启动界面时&#xff0c;发现设置的样式无效&#xff0c;效果如下&#xff1a; /* 设置下拉菜单框的样式 */ QComboBox QAbstractItemView {border: 1px solid rgb(161,161,161); /* …...

AI 对话工具汇总

&#x1f423;个人主页 可惜已不在 &#x1f424;这篇在这个专栏AI_可惜已不在的博客-CSDN博客 &#x1f425;有用的话就留下一个三连吧&#x1f63c; 目录 前言: 正文: 前言: 在科技飞速发展的时代&#xff0c;AI 对话正逐渐成为我们获取信息、交流思想的新方式。它以强…...

面试题05.08绘制直线问题详解(考察点为位运算符)

目录 一题目&#xff1a; 二详细思路汇总&#xff1a; 三代码解答&#xff08;带注释版&#xff09;&#xff1a; 一题目&#xff1a; leetcode原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 二详细思路汇总&#xff1a; 这里先剧透一下简单版思路哦&…...

埃及 Explained

古埃及&#xff0c;位于尼罗河畔的神秘文明&#xff0c;曾在北非的荒漠中繁荣昌盛。这个充满谜团的王国凭借其宏伟的成就和神秘的文化&#xff0c;数百年来吸引了无数人的好奇心。 埃及人创造了复杂的象形文字&#xff0c;建造了像吉萨大金字塔这样宏伟的建筑&#xff0c;并通…...

【Linux】第一个小程序——进度条实现

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…...

如何确定光纤用几芯 用光纤与网线区别在哪里

光纤用几芯&#xff1f; 光纤芯数&#xff0c;主要和光纤连接的设备接口和设备的通信方式有关。一般来说&#xff0c;光纤中光芯的数量&#xff0c;为设备接口总数乘以2后&#xff0c;再加上10%&#xff5e;20&#xff05;的备用数量&#xff0c;而如果设备的通信方式有设备多…...

使用Chrome浏览器时打开网页如何禁用缓存

缓存是浏览器用于临时存储网页资源的一种机制&#xff0c;可以提高网页加载速度和减轻服务器负载。 然而&#xff0c;有时候我们需要阻止缓存中的Chrome浏览器&#xff0c;以便获取最新的网页内容。以下是一些方法可以实现这个目标&#xff1a; 1、强制刷新页面&#xff1a;在C…...

zabbix7.0创建自定义模板的案例详解(以监控httpd服务为例)

前言 服务端配置 链接: rocky9.2部署zabbix服务端的详细过程 环境 主机ip应用zabbix-server192.168.10.11zabbix本体zabbix-client192.168.10.12zabbix-agent zabbix-server(服务端已配置) 创建模板 模板组直接写一个新的&#xff0c;不用选择 通过名称查找模板&#xf…...

从零开始Ubuntu24.04上Docker构建自动化部署(五)Docker安装jenkins

安装jenkins 下载 sudo docker pull jenkins/jenkins:lts docker-compose启动 jenkins: image: jenkins/jenkins:lts container_name: compose_jenkins user: root restart: always ports: - 28080:8080 volumes: - /home/jenkins_home/:/var/jenkins_home - /usr/local/bin/d…...

【JS】访问器成员

前言 如下例&#xff0c;有一商品对象&#xff0c;其中属性分别为单价和数量以及一个用于计算总价的方法&#xff0c;需要通过 product.getTotal() 获得总价&#xff0c;也可以使用访问器成员getter控制属性读写逻辑&#xff0c;通过 product.total 的方式获取总价&#xff0c…...

五子棋双人对战项目(3)——匹配模块

目录 一、分析需求 二、约定前后端交互接口 匹配请求&#xff1a; 匹配响应&#xff1a; 三、实现游戏大厅页面&#xff08;前端代码&#xff09; game_hall.html&#xff1a; common.css&#xff1a; game_hall.css&#xff1a; 四、实现后端代码 WebSocketConfig …...

开源软件简介

一、开源运动的发起 近几十年&#xff0c;软件已经称为战略性的社会资源。各大软件供应商传统的对外封锁源代码的运营模式虽说有积极的一面&#xff0c;比如可以维护开发商的利益&#xff0c;使其可以持续地维护进一步开发的能力&#xff0c;以及可以保护软件商及客户的私密信息…...

Bruno:拥有 11.2k star 的免费开源 API 测试工具

Github 开源地址&#xff1a; https://github.com/usebruno/bruno 官网地址&#xff1a; https://www.usebruno.com/ 下载地址&#xff1a; https://www.usebruno.com/downloads 使用文档&#xff1a; https://docs.usebruno.com/ Bruno 是一款全新且创新的 API 客户端&…...

C动态内存管理

前言&#xff1a;不知不觉又过去了很长的一段时间。今天对C语言中的动态内存管理进行一个系统性的总结。 1 为什么要有动态内存分配 在C语言中&#xff0c;使用int&#xff0c;float&#xff0c;double&#xff0c;short等数据内置类型以及数组不是也可以开辟内存空间吗&…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...