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

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...