当前位置: 首页 > 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等数据内置类型以及数组不是也可以开辟内存空间吗&…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...